/*
 *
 *    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.
 */

#import <Foundation/Foundation.h>

#import "MTRBaseClusterUtils.h"
#import "MTRBaseClusters_Internal.h"
#import "MTRBaseDevice_Internal.h"
#import "MTRCallbackBridge.h"
#import "MTRClusterStateCacheContainer_Internal.h"
#import "MTRCluster_Internal.h"
#import "MTRCommandPayloadsObjc.h"
#import "MTRDevice_Internal.h"
#import "MTRStructsObjc.h"

#include <controller/CHIPCluster.h>
#include <lib/support/CHIPListUtils.h>
#include <platform/CHIPDeviceLayer.h>

#include <type_traits>

using chip::Callback::Callback;
using chip::Callback::Cancelable;
using namespace chip::app::Clusters;
using chip::Optional;
using chip::SessionHandle;
using chip::Messaging::ExchangeManager;
using chip::System::Clock::Seconds16;
using chip::System::Clock::Timeout;

// NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks): Linter is unable to locate the delete on these objects.
@implementation MTRBaseClusterIdentify

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)identifyWithParams:(MTRIdentifyClusterIdentifyParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            Identify::Commands::Identify::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.identifyTime = params.identifyTime.unsignedShortValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)triggerEffectWithParams:(MTRIdentifyClusterTriggerEffectParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            Identify::Commands::TriggerEffect::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.effectIdentifier = static_cast<std::remove_reference_t<decltype(request.effectIdentifier)>>(
                params.effectIdentifier.unsignedCharValue);
            request.effectVariant
                = static_cast<std::remove_reference_t<decltype(request.effectVariant)>>(params.effectVariant.unsignedCharValue);

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeIdentifyTimeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Identify::Attributes::IdentifyTime::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeIdentifyTimeWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeIdentifyTimeWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeIdentifyTimeWithValue:(NSNumber * _Nonnull)value
                                     params:(MTRWriteParams * _Nullable)params
                                 completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Identify::Attributes::IdentifyTime::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeIdentifyTimeWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Identify::Attributes::IdentifyTime::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeIdentifyTimeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Identify::Attributes::IdentifyTime::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeIdentifyTypeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Identify::Attributes::IdentifyType::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeIdentifyTypeWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Identify::Attributes::IdentifyType::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeIdentifyTypeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Identify::Attributes::IdentifyType::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Identify::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRIdentifyGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Identify::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRIdentifyGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRIdentifyGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(IdentifyGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Identify::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Identify::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRIdentifyAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Identify::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRIdentifyAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRIdentifyAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(IdentifyAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Identify::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Identify::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRIdentifyEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Identify::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRIdentifyEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRIdentifyEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(IdentifyEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Identify::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Identify::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRIdentifyAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Identify::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRIdentifyAttributeListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRIdentifyAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(IdentifyAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Identify::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Identify::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Identify::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Identify::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Identify::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Identify::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Identify::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterIdentify (Deprecated)

- (void)identifyWithParams:(MTRIdentifyClusterIdentifyParams *)params completionHandler:(MTRStatusCompletion)completionHandler
{
    [self identifyWithParams:params completion:completionHandler];
}
- (void)triggerEffectWithParams:(MTRIdentifyClusterTriggerEffectParams *)params
              completionHandler:(MTRStatusCompletion)completionHandler
{
    [self triggerEffectWithParams:params completion:completionHandler];
}

- (void)readAttributeIdentifyTimeWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeIdentifyTimeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeIdentifyTimeWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeIdentifyTimeWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeIdentifyTimeWithValue:(NSNumber * _Nonnull)value
                                     params:(MTRWriteParams * _Nullable)params
                          completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeIdentifyTimeWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeIdentifyTimeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeIdentifyTimeWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributeIdentifyTimeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeIdentifyTimeWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributeIdentifyTypeWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeIdentifyTypeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeIdentifyTypeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeIdentifyTypeWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributeIdentifyTypeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeIdentifyTypeWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterGroups

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)addGroupWithParams:(MTRGroupsClusterAddGroupParams *)params
                completion:(void (^)(MTRGroupsClusterAddGroupResponseParams * _Nullable data, NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRGroupsClusterAddGroupResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, GroupsClusterAddGroupResponseCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRGroupsClusterAddGroupResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            Groups::Commands::AddGroup::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.groupID = params.groupID.unsignedShortValue;
            request.groupName = [self asCharSpan:params.groupName];

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)viewGroupWithParams:(MTRGroupsClusterViewGroupParams *)params
                 completion:
                     (void (^)(MTRGroupsClusterViewGroupResponseParams * _Nullable data, NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRGroupsClusterViewGroupResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, GroupsClusterViewGroupResponseCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRGroupsClusterViewGroupResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            Groups::Commands::ViewGroup::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.groupID = params.groupID.unsignedShortValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)getGroupMembershipWithParams:(MTRGroupsClusterGetGroupMembershipParams *)params
                          completion:(void (^)(MTRGroupsClusterGetGroupMembershipResponseParams * _Nullable data,
                                         NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRGroupsClusterGetGroupMembershipResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            GroupsClusterGetGroupMembershipResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRGroupsClusterGetGroupMembershipResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            Groups::Commands::GetGroupMembership::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            {
                using ListType_0 = std::remove_reference_t<decltype(request.groupList)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (params.groupList.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(params.groupList.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < params.groupList.count; ++i_0) {
                        if (![params.groupList[i_0] isKindOfClass:[NSNumber class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (NSNumber *) params.groupList[i_0];
                        listHolder_0->mList[i_0] = element_0.unsignedShortValue;
                    }
                    request.groupList = ListType_0(listHolder_0->mList, params.groupList.count);
                } else {
                    request.groupList = ListType_0();
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)removeGroupWithParams:(MTRGroupsClusterRemoveGroupParams *)params
                   completion:
                       (void (^)(MTRGroupsClusterRemoveGroupResponseParams * _Nullable data, NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRGroupsClusterRemoveGroupResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, GroupsClusterRemoveGroupResponseCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRGroupsClusterRemoveGroupResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            Groups::Commands::RemoveGroup::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.groupID = params.groupID.unsignedShortValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)removeAllGroupsWithCompletion:(MTRStatusCompletion)completion
{
    [self removeAllGroupsWithParams:nil completion:completion];
}
- (void)removeAllGroupsWithParams:(MTRGroupsClusterRemoveAllGroupsParams * _Nullable)params
                       completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            Groups::Commands::RemoveAllGroups::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)addGroupIfIdentifyingWithParams:(MTRGroupsClusterAddGroupIfIdentifyingParams *)params
                             completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            Groups::Commands::AddGroupIfIdentifying::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.groupID = params.groupID.unsignedShortValue;
            request.groupName = [self asCharSpan:params.groupName];

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeNameSupportWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Groups::Attributes::NameSupport::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeNameSupportWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Groups::Attributes::NameSupport::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNameSupportWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Groups::Attributes::NameSupport::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Groups::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRGroupsGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Groups::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRGroupsGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRGroupsGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(GroupsGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Groups::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Groups::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRGroupsAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Groups::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRGroupsAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRGroupsAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(GroupsAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Groups::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Groups::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRGroupsEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Groups::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRGroupsEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRGroupsEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(GroupsEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Groups::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Groups::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRGroupsAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Groups::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRGroupsAttributeListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRGroupsAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(GroupsAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Groups::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Groups::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Groups::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Groups::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Groups::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Groups::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Groups::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterGroups (Deprecated)

- (void)addGroupWithParams:(MTRGroupsClusterAddGroupParams *)params
         completionHandler:
             (void (^)(MTRGroupsClusterAddGroupResponseParams * _Nullable data, NSError * _Nullable error))completionHandler
{
    [self addGroupWithParams:params
                  completion:^(MTRGroupsClusterAddGroupResponseParams * _Nullable data, NSError * _Nullable error) {
                      // Cast is safe because subclass does not add any selectors.
                      completionHandler(static_cast<MTRGroupsClusterAddGroupResponseParams *>(data), error);
                  }];
}
- (void)viewGroupWithParams:(MTRGroupsClusterViewGroupParams *)params
          completionHandler:
              (void (^)(MTRGroupsClusterViewGroupResponseParams * _Nullable data, NSError * _Nullable error))completionHandler
{
    [self viewGroupWithParams:params
                   completion:^(MTRGroupsClusterViewGroupResponseParams * _Nullable data, NSError * _Nullable error) {
                       // Cast is safe because subclass does not add any selectors.
                       completionHandler(static_cast<MTRGroupsClusterViewGroupResponseParams *>(data), error);
                   }];
}
- (void)getGroupMembershipWithParams:(MTRGroupsClusterGetGroupMembershipParams *)params
                   completionHandler:(void (^)(MTRGroupsClusterGetGroupMembershipResponseParams * _Nullable data,
                                         NSError * _Nullable error))completionHandler
{
    [self getGroupMembershipWithParams:params
                            completion:^(
                                MTRGroupsClusterGetGroupMembershipResponseParams * _Nullable data, NSError * _Nullable error) {
                                // Cast is safe because subclass does not add any selectors.
                                completionHandler(static_cast<MTRGroupsClusterGetGroupMembershipResponseParams *>(data), error);
                            }];
}
- (void)removeGroupWithParams:(MTRGroupsClusterRemoveGroupParams *)params
            completionHandler:
                (void (^)(MTRGroupsClusterRemoveGroupResponseParams * _Nullable data, NSError * _Nullable error))completionHandler
{
    [self removeGroupWithParams:params
                     completion:^(MTRGroupsClusterRemoveGroupResponseParams * _Nullable data, NSError * _Nullable error) {
                         // Cast is safe because subclass does not add any selectors.
                         completionHandler(static_cast<MTRGroupsClusterRemoveGroupResponseParams *>(data), error);
                     }];
}
- (void)removeAllGroupsWithParams:(MTRGroupsClusterRemoveAllGroupsParams * _Nullable)params
                completionHandler:(MTRStatusCompletion)completionHandler
{
    [self removeAllGroupsWithParams:params completion:completionHandler];
}
- (void)removeAllGroupsWithCompletionHandler:(MTRStatusCompletion)completionHandler
{
    [self removeAllGroupsWithParams:nil completionHandler:completionHandler];
}
- (void)addGroupIfIdentifyingWithParams:(MTRGroupsClusterAddGroupIfIdentifyingParams *)params
                      completionHandler:(MTRStatusCompletion)completionHandler
{
    [self addGroupIfIdentifyingWithParams:params completion:completionHandler];
}

- (void)readAttributeNameSupportWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNameSupportWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeNameSupportWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNameSupportWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSNumber *>(value), error);
                                    }];
}
+ (void)readAttributeNameSupportWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNameSupportWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                             }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterScenes

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)addSceneWithParams:(MTRScenesClusterAddSceneParams *)params
                completion:(void (^)(MTRScenesClusterAddSceneResponseParams * _Nullable data, NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRScenesClusterAddSceneResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, ScenesClusterAddSceneResponseCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRScenesClusterAddSceneResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            Scenes::Commands::AddScene::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.groupID = params.groupID.unsignedShortValue;
            request.sceneID = params.sceneID.unsignedCharValue;
            request.transitionTime = params.transitionTime.unsignedShortValue;
            request.sceneName = [self asCharSpan:params.sceneName];
            {
                using ListType_0 = std::remove_reference_t<decltype(request.extensionFieldSets)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (params.extensionFieldSets.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(params.extensionFieldSets.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < params.extensionFieldSets.count; ++i_0) {
                        if (![params.extensionFieldSets[i_0] isKindOfClass:[MTRScenesClusterExtensionFieldSet class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (MTRScenesClusterExtensionFieldSet *) params.extensionFieldSets[i_0];
                        listHolder_0->mList[i_0].clusterID = element_0.clusterID.unsignedIntValue;
                        {
                            using ListType_2 = std::remove_reference_t<decltype(listHolder_0->mList[i_0].attributeValueList)>;
                            using ListMemberType_2 = ListMemberTypeGetter<ListType_2>::Type;
                            if (element_0.attributeValueList.count != 0) {
                                auto * listHolder_2 = new ListHolder<ListMemberType_2>(element_0.attributeValueList.count);
                                if (listHolder_2 == nullptr || listHolder_2->mList == nullptr) {
                                    return CHIP_ERROR_INVALID_ARGUMENT;
                                }
                                listFreer.add(listHolder_2);
                                for (size_t i_2 = 0; i_2 < element_0.attributeValueList.count; ++i_2) {
                                    if (![element_0.attributeValueList[i_2]
                                            isKindOfClass:[MTRScenesClusterAttributeValuePair class]]) {
                                        // Wrong kind of value.
                                        return CHIP_ERROR_INVALID_ARGUMENT;
                                    }
                                    auto element_2 = (MTRScenesClusterAttributeValuePair *) element_0.attributeValueList[i_2];
                                    if (element_2.attributeID != nil) {
                                        auto & definedValue_4 = listHolder_2->mList[i_2].attributeID.Emplace();
                                        definedValue_4 = element_2.attributeID.unsignedIntValue;
                                    }
                                    {
                                        using ListType_4
                                            = std::remove_reference_t<decltype(listHolder_2->mList[i_2].attributeValue)>;
                                        using ListMemberType_4 = ListMemberTypeGetter<ListType_4>::Type;
                                        if (element_2.attributeValue.count != 0) {
                                            auto * listHolder_4 = new ListHolder<ListMemberType_4>(element_2.attributeValue.count);
                                            if (listHolder_4 == nullptr || listHolder_4->mList == nullptr) {
                                                return CHIP_ERROR_INVALID_ARGUMENT;
                                            }
                                            listFreer.add(listHolder_4);
                                            for (size_t i_4 = 0; i_4 < element_2.attributeValue.count; ++i_4) {
                                                if (![element_2.attributeValue[i_4] isKindOfClass:[NSNumber class]]) {
                                                    // Wrong kind of value.
                                                    return CHIP_ERROR_INVALID_ARGUMENT;
                                                }
                                                auto element_4 = (NSNumber *) element_2.attributeValue[i_4];
                                                listHolder_4->mList[i_4] = element_4.unsignedCharValue;
                                            }
                                            listHolder_2->mList[i_2].attributeValue
                                                = ListType_4(listHolder_4->mList, element_2.attributeValue.count);
                                        } else {
                                            listHolder_2->mList[i_2].attributeValue = ListType_4();
                                        }
                                    }
                                }
                                listHolder_0->mList[i_0].attributeValueList
                                    = ListType_2(listHolder_2->mList, element_0.attributeValueList.count);
                            } else {
                                listHolder_0->mList[i_0].attributeValueList = ListType_2();
                            }
                        }
                    }
                    request.extensionFieldSets = ListType_0(listHolder_0->mList, params.extensionFieldSets.count);
                } else {
                    request.extensionFieldSets = ListType_0();
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)viewSceneWithParams:(MTRScenesClusterViewSceneParams *)params
                 completion:
                     (void (^)(MTRScenesClusterViewSceneResponseParams * _Nullable data, NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRScenesClusterViewSceneResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, ScenesClusterViewSceneResponseCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRScenesClusterViewSceneResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            Scenes::Commands::ViewScene::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.groupID = params.groupID.unsignedShortValue;
            request.sceneID = params.sceneID.unsignedCharValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)removeSceneWithParams:(MTRScenesClusterRemoveSceneParams *)params
                   completion:
                       (void (^)(MTRScenesClusterRemoveSceneResponseParams * _Nullable data, NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRScenesClusterRemoveSceneResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, ScenesClusterRemoveSceneResponseCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRScenesClusterRemoveSceneResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            Scenes::Commands::RemoveScene::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.groupID = params.groupID.unsignedShortValue;
            request.sceneID = params.sceneID.unsignedCharValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)removeAllScenesWithParams:(MTRScenesClusterRemoveAllScenesParams *)params
                       completion:(void (^)(MTRScenesClusterRemoveAllScenesResponseParams * _Nullable data,
                                      NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRScenesClusterRemoveAllScenesResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            ScenesClusterRemoveAllScenesResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRScenesClusterRemoveAllScenesResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            Scenes::Commands::RemoveAllScenes::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.groupID = params.groupID.unsignedShortValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)storeSceneWithParams:(MTRScenesClusterStoreSceneParams *)params
                  completion:
                      (void (^)(MTRScenesClusterStoreSceneResponseParams * _Nullable data, NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRScenesClusterStoreSceneResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, ScenesClusterStoreSceneResponseCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRScenesClusterStoreSceneResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            Scenes::Commands::StoreScene::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.groupID = params.groupID.unsignedShortValue;
            request.sceneID = params.sceneID.unsignedCharValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)recallSceneWithParams:(MTRScenesClusterRecallSceneParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            Scenes::Commands::RecallScene::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.groupID = params.groupID.unsignedShortValue;
            request.sceneID = params.sceneID.unsignedCharValue;
            if (params.transitionTime != nil) {
                auto & definedValue_0 = request.transitionTime.Emplace();
                if (params.transitionTime == nil) {
                    definedValue_0.SetNull();
                } else {
                    auto & nonNullValue_1 = definedValue_0.SetNonNull();
                    nonNullValue_1 = params.transitionTime.unsignedShortValue;
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)getSceneMembershipWithParams:(MTRScenesClusterGetSceneMembershipParams *)params
                          completion:(void (^)(MTRScenesClusterGetSceneMembershipResponseParams * _Nullable data,
                                         NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRScenesClusterGetSceneMembershipResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            ScenesClusterGetSceneMembershipResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRScenesClusterGetSceneMembershipResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            Scenes::Commands::GetSceneMembership::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.groupID = params.groupID.unsignedShortValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)enhancedAddSceneWithParams:(MTRScenesClusterEnhancedAddSceneParams *)params
                        completion:(void (^)(MTRScenesClusterEnhancedAddSceneResponseParams * _Nullable data,
                                       NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRScenesClusterEnhancedAddSceneResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            ScenesClusterEnhancedAddSceneResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRScenesClusterEnhancedAddSceneResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            Scenes::Commands::EnhancedAddScene::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.groupID = params.groupID.unsignedShortValue;
            request.sceneID = params.sceneID.unsignedCharValue;
            request.transitionTime = params.transitionTime.unsignedShortValue;
            request.sceneName = [self asCharSpan:params.sceneName];
            {
                using ListType_0 = std::remove_reference_t<decltype(request.extensionFieldSets)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (params.extensionFieldSets.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(params.extensionFieldSets.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < params.extensionFieldSets.count; ++i_0) {
                        if (![params.extensionFieldSets[i_0] isKindOfClass:[MTRScenesClusterExtensionFieldSet class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (MTRScenesClusterExtensionFieldSet *) params.extensionFieldSets[i_0];
                        listHolder_0->mList[i_0].clusterID = element_0.clusterID.unsignedIntValue;
                        {
                            using ListType_2 = std::remove_reference_t<decltype(listHolder_0->mList[i_0].attributeValueList)>;
                            using ListMemberType_2 = ListMemberTypeGetter<ListType_2>::Type;
                            if (element_0.attributeValueList.count != 0) {
                                auto * listHolder_2 = new ListHolder<ListMemberType_2>(element_0.attributeValueList.count);
                                if (listHolder_2 == nullptr || listHolder_2->mList == nullptr) {
                                    return CHIP_ERROR_INVALID_ARGUMENT;
                                }
                                listFreer.add(listHolder_2);
                                for (size_t i_2 = 0; i_2 < element_0.attributeValueList.count; ++i_2) {
                                    if (![element_0.attributeValueList[i_2]
                                            isKindOfClass:[MTRScenesClusterAttributeValuePair class]]) {
                                        // Wrong kind of value.
                                        return CHIP_ERROR_INVALID_ARGUMENT;
                                    }
                                    auto element_2 = (MTRScenesClusterAttributeValuePair *) element_0.attributeValueList[i_2];
                                    if (element_2.attributeID != nil) {
                                        auto & definedValue_4 = listHolder_2->mList[i_2].attributeID.Emplace();
                                        definedValue_4 = element_2.attributeID.unsignedIntValue;
                                    }
                                    {
                                        using ListType_4
                                            = std::remove_reference_t<decltype(listHolder_2->mList[i_2].attributeValue)>;
                                        using ListMemberType_4 = ListMemberTypeGetter<ListType_4>::Type;
                                        if (element_2.attributeValue.count != 0) {
                                            auto * listHolder_4 = new ListHolder<ListMemberType_4>(element_2.attributeValue.count);
                                            if (listHolder_4 == nullptr || listHolder_4->mList == nullptr) {
                                                return CHIP_ERROR_INVALID_ARGUMENT;
                                            }
                                            listFreer.add(listHolder_4);
                                            for (size_t i_4 = 0; i_4 < element_2.attributeValue.count; ++i_4) {
                                                if (![element_2.attributeValue[i_4] isKindOfClass:[NSNumber class]]) {
                                                    // Wrong kind of value.
                                                    return CHIP_ERROR_INVALID_ARGUMENT;
                                                }
                                                auto element_4 = (NSNumber *) element_2.attributeValue[i_4];
                                                listHolder_4->mList[i_4] = element_4.unsignedCharValue;
                                            }
                                            listHolder_2->mList[i_2].attributeValue
                                                = ListType_4(listHolder_4->mList, element_2.attributeValue.count);
                                        } else {
                                            listHolder_2->mList[i_2].attributeValue = ListType_4();
                                        }
                                    }
                                }
                                listHolder_0->mList[i_0].attributeValueList
                                    = ListType_2(listHolder_2->mList, element_0.attributeValueList.count);
                            } else {
                                listHolder_0->mList[i_0].attributeValueList = ListType_2();
                            }
                        }
                    }
                    request.extensionFieldSets = ListType_0(listHolder_0->mList, params.extensionFieldSets.count);
                } else {
                    request.extensionFieldSets = ListType_0();
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)enhancedViewSceneWithParams:(MTRScenesClusterEnhancedViewSceneParams *)params
                         completion:(void (^)(MTRScenesClusterEnhancedViewSceneResponseParams * _Nullable data,
                                        NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRScenesClusterEnhancedViewSceneResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            ScenesClusterEnhancedViewSceneResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRScenesClusterEnhancedViewSceneResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            Scenes::Commands::EnhancedViewScene::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.groupID = params.groupID.unsignedShortValue;
            request.sceneID = params.sceneID.unsignedCharValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)copySceneWithParams:(MTRScenesClusterCopySceneParams *)params
                 completion:
                     (void (^)(MTRScenesClusterCopySceneResponseParams * _Nullable data, NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRScenesClusterCopySceneResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, ScenesClusterCopySceneResponseCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRScenesClusterCopySceneResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            Scenes::Commands::CopyScene::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.mode = static_cast<std::remove_reference_t<decltype(request.mode)>>(params.mode.unsignedCharValue);
            request.groupIdentifierFrom = params.groupIdentifierFrom.unsignedShortValue;
            request.sceneIdentifierFrom = params.sceneIdentifierFrom.unsignedCharValue;
            request.groupIdentifierTo = params.groupIdentifierTo.unsignedShortValue;
            request.sceneIdentifierTo = params.sceneIdentifierTo.unsignedCharValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeSceneCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Scenes::Attributes::SceneCount::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeSceneCountWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Scenes::Attributes::SceneCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeSceneCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Scenes::Attributes::SceneCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCurrentSceneWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Scenes::Attributes::CurrentScene::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeCurrentSceneWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Scenes::Attributes::CurrentScene::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeCurrentSceneWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Scenes::Attributes::CurrentScene::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCurrentGroupWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Scenes::Attributes::CurrentGroup::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeCurrentGroupWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Scenes::Attributes::CurrentGroup::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeCurrentGroupWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Scenes::Attributes::CurrentGroup::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSceneValidWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Scenes::Attributes::SceneValid::TypeInfo;
    return MTRReadAttribute<MTRBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeSceneValidWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Scenes::Attributes::SceneValid::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeSceneValidWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Scenes::Attributes::SceneValid::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNameSupportWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Scenes::Attributes::NameSupport::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeNameSupportWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Scenes::Attributes::NameSupport::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNameSupportWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Scenes::Attributes::NameSupport::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeLastConfiguredByWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Scenes::Attributes::LastConfiguredBy::TypeInfo;
    return MTRReadAttribute<MTRNullableInt64uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeLastConfiguredByWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Scenes::Attributes::LastConfiguredBy::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt64uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeLastConfiguredByWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt64uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt64uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Scenes::Attributes::LastConfiguredBy::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Scenes::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRScenesGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Scenes::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRScenesGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRScenesGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ScenesGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Scenes::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Scenes::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRScenesAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Scenes::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRScenesAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRScenesAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ScenesAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Scenes::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Scenes::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRScenesEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Scenes::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRScenesEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRScenesEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(ScenesEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Scenes::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Scenes::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRScenesAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Scenes::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRScenesAttributeListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRScenesAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(ScenesAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Scenes::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Scenes::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Scenes::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Scenes::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Scenes::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Scenes::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Scenes::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterScenes (Deprecated)

- (void)addSceneWithParams:(MTRScenesClusterAddSceneParams *)params
         completionHandler:
             (void (^)(MTRScenesClusterAddSceneResponseParams * _Nullable data, NSError * _Nullable error))completionHandler
{
    [self addSceneWithParams:params
                  completion:^(MTRScenesClusterAddSceneResponseParams * _Nullable data, NSError * _Nullable error) {
                      // Cast is safe because subclass does not add any selectors.
                      completionHandler(static_cast<MTRScenesClusterAddSceneResponseParams *>(data), error);
                  }];
}
- (void)viewSceneWithParams:(MTRScenesClusterViewSceneParams *)params
          completionHandler:
              (void (^)(MTRScenesClusterViewSceneResponseParams * _Nullable data, NSError * _Nullable error))completionHandler
{
    [self viewSceneWithParams:params
                   completion:^(MTRScenesClusterViewSceneResponseParams * _Nullable data, NSError * _Nullable error) {
                       // Cast is safe because subclass does not add any selectors.
                       completionHandler(static_cast<MTRScenesClusterViewSceneResponseParams *>(data), error);
                   }];
}
- (void)removeSceneWithParams:(MTRScenesClusterRemoveSceneParams *)params
            completionHandler:
                (void (^)(MTRScenesClusterRemoveSceneResponseParams * _Nullable data, NSError * _Nullable error))completionHandler
{
    [self removeSceneWithParams:params
                     completion:^(MTRScenesClusterRemoveSceneResponseParams * _Nullable data, NSError * _Nullable error) {
                         // Cast is safe because subclass does not add any selectors.
                         completionHandler(static_cast<MTRScenesClusterRemoveSceneResponseParams *>(data), error);
                     }];
}
- (void)removeAllScenesWithParams:(MTRScenesClusterRemoveAllScenesParams *)params
                completionHandler:(void (^)(MTRScenesClusterRemoveAllScenesResponseParams * _Nullable data,
                                      NSError * _Nullable error))completionHandler
{
    [self removeAllScenesWithParams:params
                         completion:^(MTRScenesClusterRemoveAllScenesResponseParams * _Nullable data, NSError * _Nullable error) {
                             // Cast is safe because subclass does not add any selectors.
                             completionHandler(static_cast<MTRScenesClusterRemoveAllScenesResponseParams *>(data), error);
                         }];
}
- (void)storeSceneWithParams:(MTRScenesClusterStoreSceneParams *)params
           completionHandler:
               (void (^)(MTRScenesClusterStoreSceneResponseParams * _Nullable data, NSError * _Nullable error))completionHandler
{
    [self storeSceneWithParams:params
                    completion:^(MTRScenesClusterStoreSceneResponseParams * _Nullable data, NSError * _Nullable error) {
                        // Cast is safe because subclass does not add any selectors.
                        completionHandler(static_cast<MTRScenesClusterStoreSceneResponseParams *>(data), error);
                    }];
}
- (void)recallSceneWithParams:(MTRScenesClusterRecallSceneParams *)params completionHandler:(MTRStatusCompletion)completionHandler
{
    [self recallSceneWithParams:params completion:completionHandler];
}
- (void)getSceneMembershipWithParams:(MTRScenesClusterGetSceneMembershipParams *)params
                   completionHandler:(void (^)(MTRScenesClusterGetSceneMembershipResponseParams * _Nullable data,
                                         NSError * _Nullable error))completionHandler
{
    [self getSceneMembershipWithParams:params
                            completion:^(
                                MTRScenesClusterGetSceneMembershipResponseParams * _Nullable data, NSError * _Nullable error) {
                                // Cast is safe because subclass does not add any selectors.
                                completionHandler(static_cast<MTRScenesClusterGetSceneMembershipResponseParams *>(data), error);
                            }];
}
- (void)enhancedAddSceneWithParams:(MTRScenesClusterEnhancedAddSceneParams *)params
                 completionHandler:(void (^)(MTRScenesClusterEnhancedAddSceneResponseParams * _Nullable data,
                                       NSError * _Nullable error))completionHandler
{
    [self enhancedAddSceneWithParams:params
                          completion:^(MTRScenesClusterEnhancedAddSceneResponseParams * _Nullable data, NSError * _Nullable error) {
                              // Cast is safe because subclass does not add any selectors.
                              completionHandler(static_cast<MTRScenesClusterEnhancedAddSceneResponseParams *>(data), error);
                          }];
}
- (void)enhancedViewSceneWithParams:(MTRScenesClusterEnhancedViewSceneParams *)params
                  completionHandler:(void (^)(MTRScenesClusterEnhancedViewSceneResponseParams * _Nullable data,
                                        NSError * _Nullable error))completionHandler
{
    [self
        enhancedViewSceneWithParams:params
                         completion:^(MTRScenesClusterEnhancedViewSceneResponseParams * _Nullable data, NSError * _Nullable error) {
                             // Cast is safe because subclass does not add any selectors.
                             completionHandler(static_cast<MTRScenesClusterEnhancedViewSceneResponseParams *>(data), error);
                         }];
}
- (void)copySceneWithParams:(MTRScenesClusterCopySceneParams *)params
          completionHandler:
              (void (^)(MTRScenesClusterCopySceneResponseParams * _Nullable data, NSError * _Nullable error))completionHandler
{
    [self copySceneWithParams:params
                   completion:^(MTRScenesClusterCopySceneResponseParams * _Nullable data, NSError * _Nullable error) {
                       // Cast is safe because subclass does not add any selectors.
                       completionHandler(static_cast<MTRScenesClusterCopySceneResponseParams *>(data), error);
                   }];
}

- (void)readAttributeSceneCountWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSceneCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeSceneCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeSceneCountWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeSceneCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSceneCountWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeCurrentSceneWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentSceneWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeCurrentSceneWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeCurrentSceneWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributeCurrentSceneWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentSceneWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributeCurrentGroupWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentGroupWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeCurrentGroupWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeCurrentGroupWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributeCurrentGroupWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentGroupWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributeSceneValidWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSceneValidWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeSceneValidWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeSceneValidWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeSceneValidWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSceneValidWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeNameSupportWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNameSupportWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeNameSupportWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNameSupportWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSNumber *>(value), error);
                                    }];
}
+ (void)readAttributeNameSupportWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNameSupportWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                             }];
}

- (void)readAttributeLastConfiguredByWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeLastConfiguredByWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)
    subscribeAttributeLastConfiguredByWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeLastConfiguredByWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributeLastConfiguredByWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLastConfiguredByWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterOnOff

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)offWithCompletion:(MTRStatusCompletion)completion
{
    [self offWithParams:nil completion:completion];
}
- (void)offWithParams:(MTROnOffClusterOffParams * _Nullable)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            OnOff::Commands::Off::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)onWithCompletion:(MTRStatusCompletion)completion
{
    [self onWithParams:nil completion:completion];
}
- (void)onWithParams:(MTROnOffClusterOnParams * _Nullable)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            OnOff::Commands::On::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)toggleWithCompletion:(MTRStatusCompletion)completion
{
    [self toggleWithParams:nil completion:completion];
}
- (void)toggleWithParams:(MTROnOffClusterToggleParams * _Nullable)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            OnOff::Commands::Toggle::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)offWithEffectWithParams:(MTROnOffClusterOffWithEffectParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            OnOff::Commands::OffWithEffect::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.effectIdentifier = static_cast<std::remove_reference_t<decltype(request.effectIdentifier)>>(
                params.effectIdentifier.unsignedCharValue);
            request.effectVariant = params.effectVariant.unsignedCharValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)onWithRecallGlobalSceneWithCompletion:(MTRStatusCompletion)completion
{
    [self onWithRecallGlobalSceneWithParams:nil completion:completion];
}
- (void)onWithRecallGlobalSceneWithParams:(MTROnOffClusterOnWithRecallGlobalSceneParams * _Nullable)params
                               completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            OnOff::Commands::OnWithRecallGlobalScene::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)onWithTimedOffWithParams:(MTROnOffClusterOnWithTimedOffParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            OnOff::Commands::OnWithTimedOff::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.onOffControl
                = static_cast<std::remove_reference_t<decltype(request.onOffControl)>>(params.onOffControl.unsignedCharValue);
            request.onTime = params.onTime.unsignedShortValue;
            request.offWaitTime = params.offWaitTime.unsignedShortValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeOnOffWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OnOff::Attributes::OnOff::TypeInfo;
    return MTRReadAttribute<MTRBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeOnOffWithParams:(MTRSubscribeParams * _Nonnull)params
                  subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                            reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OnOff::Attributes::OnOff::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeOnOffWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                                     completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OnOff::Attributes::OnOff::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGlobalSceneControlWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OnOff::Attributes::GlobalSceneControl::TypeInfo;
    return MTRReadAttribute<MTRBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGlobalSceneControlWithParams:(MTRSubscribeParams * _Nonnull)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OnOff::Attributes::GlobalSceneControl::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeGlobalSceneControlWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                                  completion:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OnOff::Attributes::GlobalSceneControl::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeOnTimeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OnOff::Attributes::OnTime::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeOnTimeWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeOnTimeWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeOnTimeWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                           completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = OnOff::Attributes::OnTime::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeOnTimeWithParams:(MTRSubscribeParams * _Nonnull)params
                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                             reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OnOff::Attributes::OnTime::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeOnTimeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                                      completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OnOff::Attributes::OnTime::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeOffWaitTimeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OnOff::Attributes::OffWaitTime::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeOffWaitTimeWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeOffWaitTimeWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeOffWaitTimeWithValue:(NSNumber * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                                completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = OnOff::Attributes::OffWaitTime::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeOffWaitTimeWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OnOff::Attributes::OffWaitTime::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeOffWaitTimeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OnOff::Attributes::OffWaitTime::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeStartUpOnOffWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OnOff::Attributes::StartUpOnOff::TypeInfo;
    return MTRReadAttribute<MTRNullableOnOffClusterOnOffStartUpOnOffAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeStartUpOnOffWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeStartUpOnOffWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeStartUpOnOffWithValue:(NSNumber * _Nullable)value
                                     params:(MTRWriteParams * _Nullable)params
                                 completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = OnOff::Attributes::StartUpOnOff::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = static_cast<std::remove_reference_t<decltype(nonNullValue_0)>>(value.unsignedCharValue);
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeStartUpOnOffWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OnOff::Attributes::StartUpOnOff::TypeInfo;
    MTRSubscribeAttribute<MTRNullableOnOffClusterOnOffStartUpOnOffAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeStartUpOnOffWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableOnOffClusterOnOffStartUpOnOffAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(NullableOnOffClusterOnOffStartUpOnOffAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OnOff::Attributes::StartUpOnOff::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OnOff::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTROnOffGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OnOff::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTROnOffGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTROnOffGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(OnOffGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OnOff::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OnOff::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTROnOffAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OnOff::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTROnOffAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTROnOffAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(OnOffAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OnOff::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OnOff::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTROnOffEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OnOff::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTROnOffEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTROnOffEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(OnOffEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OnOff::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OnOff::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTROnOffAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OnOff::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTROnOffAttributeListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTROnOffAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(OnOffAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OnOff::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OnOff::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OnOff::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OnOff::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OnOff::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OnOff::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OnOff::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterOnOff (Deprecated)

- (void)offWithParams:(MTROnOffClusterOffParams * _Nullable)params completionHandler:(MTRStatusCompletion)completionHandler
{
    [self offWithParams:params completion:completionHandler];
}
- (void)offWithCompletionHandler:(MTRStatusCompletion)completionHandler
{
    [self offWithParams:nil completionHandler:completionHandler];
}
- (void)onWithParams:(MTROnOffClusterOnParams * _Nullable)params completionHandler:(MTRStatusCompletion)completionHandler
{
    [self onWithParams:params completion:completionHandler];
}
- (void)onWithCompletionHandler:(MTRStatusCompletion)completionHandler
{
    [self onWithParams:nil completionHandler:completionHandler];
}
- (void)toggleWithParams:(MTROnOffClusterToggleParams * _Nullable)params completionHandler:(MTRStatusCompletion)completionHandler
{
    [self toggleWithParams:params completion:completionHandler];
}
- (void)toggleWithCompletionHandler:(MTRStatusCompletion)completionHandler
{
    [self toggleWithParams:nil completionHandler:completionHandler];
}
- (void)offWithEffectWithParams:(MTROnOffClusterOffWithEffectParams *)params
              completionHandler:(MTRStatusCompletion)completionHandler
{
    [self offWithEffectWithParams:params completion:completionHandler];
}
- (void)onWithRecallGlobalSceneWithParams:(MTROnOffClusterOnWithRecallGlobalSceneParams * _Nullable)params
                        completionHandler:(MTRStatusCompletion)completionHandler
{
    [self onWithRecallGlobalSceneWithParams:params completion:completionHandler];
}
- (void)onWithRecallGlobalSceneWithCompletionHandler:(MTRStatusCompletion)completionHandler
{
    [self onWithRecallGlobalSceneWithParams:nil completionHandler:completionHandler];
}
- (void)onWithTimedOffWithParams:(MTROnOffClusterOnWithTimedOffParams *)params
               completionHandler:(MTRStatusCompletion)completionHandler
{
    [self onWithTimedOffWithParams:params completion:completionHandler];
}

- (void)readAttributeOnOffWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOnOffWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeOnOffWithMinInterval:(NSNumber * _Nonnull)minInterval
                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                        params:(MTRSubscribeParams * _Nullable)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeOnOffWithParams:subscribeParams
                    subscriptionEstablished:subscriptionEstablishedHandler
                              reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                  // Cast is safe because subclass does not add any selectors.
                                  reportHandler(static_cast<NSNumber *>(value), error);
                              }];
}
+ (void)readAttributeOnOffWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                    endpoint:(NSNumber *)endpoint
                                       queue:(dispatch_queue_t)queue
                           completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOnOffWithClusterStateCache:attributeCacheContainer.realContainer
                                         endpoint:endpoint
                                            queue:queue
                                       completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           completionHandler(static_cast<NSNumber *>(value), error);
                                       }];
}

- (void)readAttributeGlobalSceneControlWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    [self readAttributeGlobalSceneControlWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeGlobalSceneControlWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:
                                        (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGlobalSceneControlWithParams:subscribeParams
                                 subscriptionEstablished:subscriptionEstablishedHandler
                                           reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               reportHandler(static_cast<NSNumber *>(value), error);
                                           }];
}
+ (void)readAttributeGlobalSceneControlWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGlobalSceneControlWithClusterStateCache:attributeCacheContainer.realContainer
                                                      endpoint:endpoint
                                                         queue:queue
                                                    completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                        // Cast is safe because subclass does not add any selectors.
                                                        completionHandler(static_cast<NSNumber *>(value), error);
                                                    }];
}

- (void)readAttributeOnTimeWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOnTimeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeOnTimeWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeOnTimeWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeOnTimeWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                    completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeOnTimeWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeOnTimeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeOnTimeWithParams:subscribeParams
                     subscriptionEstablished:subscriptionEstablishedHandler
                               reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                   // Cast is safe because subclass does not add any selectors.
                                   reportHandler(static_cast<NSNumber *>(value), error);
                               }];
}
+ (void)readAttributeOnTimeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOnTimeWithClusterStateCache:attributeCacheContainer.realContainer
                                          endpoint:endpoint
                                             queue:queue
                                        completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            completionHandler(static_cast<NSNumber *>(value), error);
                                        }];
}

- (void)readAttributeOffWaitTimeWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOffWaitTimeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeOffWaitTimeWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeOffWaitTimeWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeOffWaitTimeWithValue:(NSNumber * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                         completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeOffWaitTimeWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeOffWaitTimeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeOffWaitTimeWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSNumber *>(value), error);
                                    }];
}
+ (void)readAttributeOffWaitTimeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOffWaitTimeWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                             }];
}

- (void)readAttributeStartUpOnOffWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeStartUpOnOffWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeStartUpOnOffWithValue:(NSNumber * _Nullable)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeStartUpOnOffWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeStartUpOnOffWithValue:(NSNumber * _Nullable)value
                                     params:(MTRWriteParams * _Nullable)params
                          completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeStartUpOnOffWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeStartUpOnOffWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeStartUpOnOffWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributeStartUpOnOffWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeStartUpOnOffWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterOnOffSwitchConfiguration

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)readAttributeSwitchTypeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OnOffSwitchConfiguration::Attributes::SwitchType::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeSwitchTypeWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OnOffSwitchConfiguration::Attributes::SwitchType::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeSwitchTypeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OnOffSwitchConfiguration::Attributes::SwitchType::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSwitchActionsWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OnOffSwitchConfiguration::Attributes::SwitchActions::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeSwitchActionsWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeSwitchActionsWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeSwitchActionsWithValue:(NSNumber * _Nonnull)value
                                      params:(MTRWriteParams * _Nullable)params
                                  completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = OnOffSwitchConfiguration::Attributes::SwitchActions::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeSwitchActionsWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OnOffSwitchConfiguration::Attributes::SwitchActions::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeSwitchActionsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OnOffSwitchConfiguration::Attributes::SwitchActions::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OnOffSwitchConfiguration::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTROnOffSwitchConfigurationGeneratedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OnOffSwitchConfiguration::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTROnOffSwitchConfigurationGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTROnOffSwitchConfigurationGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(OnOffSwitchConfigurationGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OnOffSwitchConfiguration::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OnOffSwitchConfiguration::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTROnOffSwitchConfigurationAcceptedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OnOffSwitchConfiguration::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTROnOffSwitchConfigurationAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTROnOffSwitchConfigurationAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(OnOffSwitchConfigurationAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OnOffSwitchConfiguration::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OnOffSwitchConfiguration::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTROnOffSwitchConfigurationEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OnOffSwitchConfiguration::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTROnOffSwitchConfigurationEventListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTROnOffSwitchConfigurationEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(OnOffSwitchConfigurationEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OnOffSwitchConfiguration::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OnOffSwitchConfiguration::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTROnOffSwitchConfigurationAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OnOffSwitchConfiguration::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTROnOffSwitchConfigurationAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTROnOffSwitchConfigurationAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(OnOffSwitchConfigurationAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OnOffSwitchConfiguration::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OnOffSwitchConfiguration::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OnOffSwitchConfiguration::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OnOffSwitchConfiguration::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OnOffSwitchConfiguration::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OnOffSwitchConfiguration::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OnOffSwitchConfiguration::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterOnOffSwitchConfiguration (Deprecated)

- (void)readAttributeSwitchTypeWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSwitchTypeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeSwitchTypeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeSwitchTypeWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeSwitchTypeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSwitchTypeWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeSwitchActionsWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSwitchActionsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeSwitchActionsWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeSwitchActionsWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeSwitchActionsWithValue:(NSNumber * _Nonnull)value
                                      params:(MTRWriteParams * _Nullable)params
                           completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeSwitchActionsWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeSwitchActionsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeSwitchActionsWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributeSwitchActionsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSwitchActionsWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterLevelControl

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)moveToLevelWithParams:(MTRLevelControlClusterMoveToLevelParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            LevelControl::Commands::MoveToLevel::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.level = params.level.unsignedCharValue;
            if (params.transitionTime == nil) {
                request.transitionTime.SetNull();
            } else {
                auto & nonNullValue_0 = request.transitionTime.SetNonNull();
                nonNullValue_0 = params.transitionTime.unsignedShortValue;
            }
            request.optionsMask
                = static_cast<std::remove_reference_t<decltype(request.optionsMask)>>(params.optionsMask.unsignedCharValue);
            request.optionsOverride
                = static_cast<std::remove_reference_t<decltype(request.optionsOverride)>>(params.optionsOverride.unsignedCharValue);

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)moveWithParams:(MTRLevelControlClusterMoveParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            LevelControl::Commands::Move::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.moveMode = static_cast<std::remove_reference_t<decltype(request.moveMode)>>(params.moveMode.unsignedCharValue);
            if (params.rate == nil) {
                request.rate.SetNull();
            } else {
                auto & nonNullValue_0 = request.rate.SetNonNull();
                nonNullValue_0 = params.rate.unsignedCharValue;
            }
            request.optionsMask
                = static_cast<std::remove_reference_t<decltype(request.optionsMask)>>(params.optionsMask.unsignedCharValue);
            request.optionsOverride
                = static_cast<std::remove_reference_t<decltype(request.optionsOverride)>>(params.optionsOverride.unsignedCharValue);

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)stepWithParams:(MTRLevelControlClusterStepParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            LevelControl::Commands::Step::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.stepMode = static_cast<std::remove_reference_t<decltype(request.stepMode)>>(params.stepMode.unsignedCharValue);
            request.stepSize = params.stepSize.unsignedCharValue;
            if (params.transitionTime == nil) {
                request.transitionTime.SetNull();
            } else {
                auto & nonNullValue_0 = request.transitionTime.SetNonNull();
                nonNullValue_0 = params.transitionTime.unsignedShortValue;
            }
            request.optionsMask
                = static_cast<std::remove_reference_t<decltype(request.optionsMask)>>(params.optionsMask.unsignedCharValue);
            request.optionsOverride
                = static_cast<std::remove_reference_t<decltype(request.optionsOverride)>>(params.optionsOverride.unsignedCharValue);

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)stopWithParams:(MTRLevelControlClusterStopParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            LevelControl::Commands::Stop::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.optionsMask
                = static_cast<std::remove_reference_t<decltype(request.optionsMask)>>(params.optionsMask.unsignedCharValue);
            request.optionsOverride
                = static_cast<std::remove_reference_t<decltype(request.optionsOverride)>>(params.optionsOverride.unsignedCharValue);

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)moveToLevelWithOnOffWithParams:(MTRLevelControlClusterMoveToLevelWithOnOffParams *)params
                            completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            LevelControl::Commands::MoveToLevelWithOnOff::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.level = params.level.unsignedCharValue;
            if (params.transitionTime == nil) {
                request.transitionTime.SetNull();
            } else {
                auto & nonNullValue_0 = request.transitionTime.SetNonNull();
                nonNullValue_0 = params.transitionTime.unsignedShortValue;
            }
            request.optionsMask
                = static_cast<std::remove_reference_t<decltype(request.optionsMask)>>(params.optionsMask.unsignedCharValue);
            request.optionsOverride
                = static_cast<std::remove_reference_t<decltype(request.optionsOverride)>>(params.optionsOverride.unsignedCharValue);

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)moveWithOnOffWithParams:(MTRLevelControlClusterMoveWithOnOffParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            LevelControl::Commands::MoveWithOnOff::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.moveMode = static_cast<std::remove_reference_t<decltype(request.moveMode)>>(params.moveMode.unsignedCharValue);
            if (params.rate == nil) {
                request.rate.SetNull();
            } else {
                auto & nonNullValue_0 = request.rate.SetNonNull();
                nonNullValue_0 = params.rate.unsignedCharValue;
            }
            request.optionsMask
                = static_cast<std::remove_reference_t<decltype(request.optionsMask)>>(params.optionsMask.unsignedCharValue);
            request.optionsOverride
                = static_cast<std::remove_reference_t<decltype(request.optionsOverride)>>(params.optionsOverride.unsignedCharValue);

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)stepWithOnOffWithParams:(MTRLevelControlClusterStepWithOnOffParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            LevelControl::Commands::StepWithOnOff::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.stepMode = static_cast<std::remove_reference_t<decltype(request.stepMode)>>(params.stepMode.unsignedCharValue);
            request.stepSize = params.stepSize.unsignedCharValue;
            if (params.transitionTime == nil) {
                request.transitionTime.SetNull();
            } else {
                auto & nonNullValue_0 = request.transitionTime.SetNonNull();
                nonNullValue_0 = params.transitionTime.unsignedShortValue;
            }
            request.optionsMask
                = static_cast<std::remove_reference_t<decltype(request.optionsMask)>>(params.optionsMask.unsignedCharValue);
            request.optionsOverride
                = static_cast<std::remove_reference_t<decltype(request.optionsOverride)>>(params.optionsOverride.unsignedCharValue);

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)stopWithOnOffWithParams:(MTRLevelControlClusterStopWithOnOffParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            LevelControl::Commands::StopWithOnOff::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.optionsMask
                = static_cast<std::remove_reference_t<decltype(request.optionsMask)>>(params.optionsMask.unsignedCharValue);
            request.optionsOverride
                = static_cast<std::remove_reference_t<decltype(request.optionsOverride)>>(params.optionsOverride.unsignedCharValue);

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)moveToClosestFrequencyWithParams:(MTRLevelControlClusterMoveToClosestFrequencyParams *)params
                              completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            LevelControl::Commands::MoveToClosestFrequency::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.frequency = params.frequency.unsignedShortValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeCurrentLevelWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = LevelControl::Attributes::CurrentLevel::TypeInfo;
    return MTRReadAttribute<MTRNullableInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeCurrentLevelWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = LevelControl::Attributes::CurrentLevel::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeCurrentLevelWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LevelControl::Attributes::CurrentLevel::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRemainingTimeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = LevelControl::Attributes::RemainingTime::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRemainingTimeWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = LevelControl::Attributes::RemainingTime::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRemainingTimeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LevelControl::Attributes::RemainingTime::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMinLevelWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = LevelControl::Attributes::MinLevel::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMinLevelWithParams:(MTRSubscribeParams * _Nonnull)params
                     subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                               reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = LevelControl::Attributes::MinLevel::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMinLevelWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                        completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LevelControl::Attributes::MinLevel::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMaxLevelWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = LevelControl::Attributes::MaxLevel::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMaxLevelWithParams:(MTRSubscribeParams * _Nonnull)params
                     subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                               reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = LevelControl::Attributes::MaxLevel::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMaxLevelWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                        completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LevelControl::Attributes::MaxLevel::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCurrentFrequencyWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = LevelControl::Attributes::CurrentFrequency::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeCurrentFrequencyWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = LevelControl::Attributes::CurrentFrequency::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeCurrentFrequencyWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LevelControl::Attributes::CurrentFrequency::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMinFrequencyWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = LevelControl::Attributes::MinFrequency::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMinFrequencyWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = LevelControl::Attributes::MinFrequency::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMinFrequencyWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LevelControl::Attributes::MinFrequency::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMaxFrequencyWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = LevelControl::Attributes::MaxFrequency::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMaxFrequencyWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = LevelControl::Attributes::MaxFrequency::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMaxFrequencyWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LevelControl::Attributes::MaxFrequency::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeOptionsWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = LevelControl::Attributes::Options::TypeInfo;
    return MTRReadAttribute<MTRLevelControlOptionsAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeOptionsWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeOptionsWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeOptionsWithValue:(NSNumber * _Nonnull)value
                                params:(MTRWriteParams * _Nullable)params
                            completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = LevelControl::Attributes::Options::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = static_cast<std::remove_reference_t<decltype(cppValue)>>(value.unsignedCharValue);

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeOptionsWithParams:(MTRSubscribeParams * _Nonnull)params
                    subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                              reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = LevelControl::Attributes::Options::TypeInfo;
    MTRSubscribeAttribute<MTRLevelControlOptionsAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeOptionsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                       completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRLevelControlOptionsAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(LevelControlOptionsAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LevelControl::Attributes::Options::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeOnOffTransitionTimeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = LevelControl::Attributes::OnOffTransitionTime::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeOnOffTransitionTimeWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeOnOffTransitionTimeWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeOnOffTransitionTimeWithValue:(NSNumber * _Nonnull)value
                                            params:(MTRWriteParams * _Nullable)params
                                        completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = LevelControl::Attributes::OnOffTransitionTime::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeOnOffTransitionTimeWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = LevelControl::Attributes::OnOffTransitionTime::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeOnOffTransitionTimeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LevelControl::Attributes::OnOffTransitionTime::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeOnLevelWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = LevelControl::Attributes::OnLevel::TypeInfo;
    return MTRReadAttribute<MTRNullableInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeOnLevelWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeOnLevelWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeOnLevelWithValue:(NSNumber * _Nullable)value
                                params:(MTRWriteParams * _Nullable)params
                            completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = LevelControl::Attributes::OnLevel::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedCharValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeOnLevelWithParams:(MTRSubscribeParams * _Nonnull)params
                    subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                              reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = LevelControl::Attributes::OnLevel::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeOnLevelWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                       completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LevelControl::Attributes::OnLevel::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeOnTransitionTimeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = LevelControl::Attributes::OnTransitionTime::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeOnTransitionTimeWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeOnTransitionTimeWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeOnTransitionTimeWithValue:(NSNumber * _Nullable)value
                                         params:(MTRWriteParams * _Nullable)params
                                     completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = LevelControl::Attributes::OnTransitionTime::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedShortValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeOnTransitionTimeWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = LevelControl::Attributes::OnTransitionTime::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeOnTransitionTimeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LevelControl::Attributes::OnTransitionTime::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeOffTransitionTimeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = LevelControl::Attributes::OffTransitionTime::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeOffTransitionTimeWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeOffTransitionTimeWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeOffTransitionTimeWithValue:(NSNumber * _Nullable)value
                                          params:(MTRWriteParams * _Nullable)params
                                      completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = LevelControl::Attributes::OffTransitionTime::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedShortValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeOffTransitionTimeWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = LevelControl::Attributes::OffTransitionTime::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeOffTransitionTimeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LevelControl::Attributes::OffTransitionTime::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeDefaultMoveRateWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = LevelControl::Attributes::DefaultMoveRate::TypeInfo;
    return MTRReadAttribute<MTRNullableInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeDefaultMoveRateWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeDefaultMoveRateWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeDefaultMoveRateWithValue:(NSNumber * _Nullable)value
                                        params:(MTRWriteParams * _Nullable)params
                                    completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = LevelControl::Attributes::DefaultMoveRate::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedCharValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeDefaultMoveRateWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = LevelControl::Attributes::DefaultMoveRate::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeDefaultMoveRateWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LevelControl::Attributes::DefaultMoveRate::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeStartUpCurrentLevelWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = LevelControl::Attributes::StartUpCurrentLevel::TypeInfo;
    return MTRReadAttribute<MTRNullableInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeStartUpCurrentLevelWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeStartUpCurrentLevelWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeStartUpCurrentLevelWithValue:(NSNumber * _Nullable)value
                                            params:(MTRWriteParams * _Nullable)params
                                        completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = LevelControl::Attributes::StartUpCurrentLevel::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedCharValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeStartUpCurrentLevelWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = LevelControl::Attributes::StartUpCurrentLevel::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeStartUpCurrentLevelWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LevelControl::Attributes::StartUpCurrentLevel::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = LevelControl::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRLevelControlGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = LevelControl::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRLevelControlGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRLevelControlGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(LevelControlGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LevelControl::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = LevelControl::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRLevelControlAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = LevelControl::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRLevelControlAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRLevelControlAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(LevelControlAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LevelControl::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = LevelControl::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRLevelControlEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = LevelControl::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRLevelControlEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRLevelControlEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(LevelControlEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LevelControl::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = LevelControl::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRLevelControlAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = LevelControl::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRLevelControlAttributeListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRLevelControlAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(LevelControlAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LevelControl::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = LevelControl::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = LevelControl::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LevelControl::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = LevelControl::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = LevelControl::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LevelControl::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterLevelControl (Deprecated)

- (void)moveToLevelWithParams:(MTRLevelControlClusterMoveToLevelParams *)params
            completionHandler:(MTRStatusCompletion)completionHandler
{
    [self moveToLevelWithParams:params completion:completionHandler];
}
- (void)moveWithParams:(MTRLevelControlClusterMoveParams *)params completionHandler:(MTRStatusCompletion)completionHandler
{
    [self moveWithParams:params completion:completionHandler];
}
- (void)stepWithParams:(MTRLevelControlClusterStepParams *)params completionHandler:(MTRStatusCompletion)completionHandler
{
    [self stepWithParams:params completion:completionHandler];
}
- (void)stopWithParams:(MTRLevelControlClusterStopParams *)params completionHandler:(MTRStatusCompletion)completionHandler
{
    [self stopWithParams:params completion:completionHandler];
}
- (void)moveToLevelWithOnOffWithParams:(MTRLevelControlClusterMoveToLevelWithOnOffParams *)params
                     completionHandler:(MTRStatusCompletion)completionHandler
{
    [self moveToLevelWithOnOffWithParams:params completion:completionHandler];
}
- (void)moveWithOnOffWithParams:(MTRLevelControlClusterMoveWithOnOffParams *)params
              completionHandler:(MTRStatusCompletion)completionHandler
{
    [self moveWithOnOffWithParams:params completion:completionHandler];
}
- (void)stepWithOnOffWithParams:(MTRLevelControlClusterStepWithOnOffParams *)params
              completionHandler:(MTRStatusCompletion)completionHandler
{
    [self stepWithOnOffWithParams:params completion:completionHandler];
}
- (void)stopWithOnOffWithParams:(MTRLevelControlClusterStopWithOnOffParams *)params
              completionHandler:(MTRStatusCompletion)completionHandler
{
    [self stopWithOnOffWithParams:params completion:completionHandler];
}
- (void)moveToClosestFrequencyWithParams:(MTRLevelControlClusterMoveToClosestFrequencyParams *)params
                       completionHandler:(MTRStatusCompletion)completionHandler
{
    [self moveToClosestFrequencyWithParams:params completion:completionHandler];
}

- (void)readAttributeCurrentLevelWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentLevelWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeCurrentLevelWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeCurrentLevelWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributeCurrentLevelWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentLevelWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributeRemainingTimeWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRemainingTimeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRemainingTimeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRemainingTimeWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributeRemainingTimeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRemainingTimeWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributeMinLevelWithCompletionHandler:(void (^)(
                                                       NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMinLevelWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeMinLevelWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMinLevelWithParams:subscribeParams
                       subscriptionEstablished:subscriptionEstablishedHandler
                                 reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                     // Cast is safe because subclass does not add any selectors.
                                     reportHandler(static_cast<NSNumber *>(value), error);
                                 }];
}
+ (void)readAttributeMinLevelWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMinLevelWithClusterStateCache:attributeCacheContainer.realContainer
                                            endpoint:endpoint
                                               queue:queue
                                          completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              completionHandler(static_cast<NSNumber *>(value), error);
                                          }];
}

- (void)readAttributeMaxLevelWithCompletionHandler:(void (^)(
                                                       NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxLevelWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeMaxLevelWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMaxLevelWithParams:subscribeParams
                       subscriptionEstablished:subscriptionEstablishedHandler
                                 reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                     // Cast is safe because subclass does not add any selectors.
                                     reportHandler(static_cast<NSNumber *>(value), error);
                                 }];
}
+ (void)readAttributeMaxLevelWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxLevelWithClusterStateCache:attributeCacheContainer.realContainer
                                            endpoint:endpoint
                                               queue:queue
                                          completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              completionHandler(static_cast<NSNumber *>(value), error);
                                          }];
}

- (void)readAttributeCurrentFrequencyWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentFrequencyWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)
    subscribeAttributeCurrentFrequencyWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeCurrentFrequencyWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributeCurrentFrequencyWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentFrequencyWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeMinFrequencyWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMinFrequencyWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeMinFrequencyWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMinFrequencyWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributeMinFrequencyWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMinFrequencyWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributeMaxFrequencyWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxFrequencyWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeMaxFrequencyWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMaxFrequencyWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributeMaxFrequencyWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxFrequencyWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributeOptionsWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOptionsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeOptionsWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeOptionsWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeOptionsWithValue:(NSNumber * _Nonnull)value
                                params:(MTRWriteParams * _Nullable)params
                     completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeOptionsWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeOptionsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                          params:(MTRSubscribeParams * _Nullable)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeOptionsWithParams:subscribeParams
                      subscriptionEstablished:subscriptionEstablishedHandler
                                reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                    // Cast is safe because subclass does not add any selectors.
                                    reportHandler(static_cast<NSNumber *>(value), error);
                                }];
}
+ (void)readAttributeOptionsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                      endpoint:(NSNumber *)endpoint
                                         queue:(dispatch_queue_t)queue
                             completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOptionsWithClusterStateCache:attributeCacheContainer.realContainer
                                           endpoint:endpoint
                                              queue:queue
                                         completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             completionHandler(static_cast<NSNumber *>(value), error);
                                         }];
}

- (void)readAttributeOnOffTransitionTimeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeOnOffTransitionTimeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeOnOffTransitionTimeWithValue:(NSNumber * _Nonnull)value
                                 completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeOnOffTransitionTimeWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeOnOffTransitionTimeWithValue:(NSNumber * _Nonnull)value
                                            params:(MTRWriteParams * _Nullable)params
                                 completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeOnOffTransitionTimeWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeOnOffTransitionTimeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeOnOffTransitionTimeWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSNumber *>(value), error);
                                            }];
}
+ (void)readAttributeOnOffTransitionTimeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOnOffTransitionTimeWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}

- (void)readAttributeOnLevelWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOnLevelWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeOnLevelWithValue:(NSNumber * _Nullable)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeOnLevelWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeOnLevelWithValue:(NSNumber * _Nullable)value
                                params:(MTRWriteParams * _Nullable)params
                     completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeOnLevelWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeOnLevelWithMinInterval:(NSNumber * _Nonnull)minInterval
                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                          params:(MTRSubscribeParams * _Nullable)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeOnLevelWithParams:subscribeParams
                      subscriptionEstablished:subscriptionEstablishedHandler
                                reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                    // Cast is safe because subclass does not add any selectors.
                                    reportHandler(static_cast<NSNumber *>(value), error);
                                }];
}
+ (void)readAttributeOnLevelWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                      endpoint:(NSNumber *)endpoint
                                         queue:(dispatch_queue_t)queue
                             completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOnLevelWithClusterStateCache:attributeCacheContainer.realContainer
                                           endpoint:endpoint
                                              queue:queue
                                         completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             completionHandler(static_cast<NSNumber *>(value), error);
                                         }];
}

- (void)readAttributeOnTransitionTimeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeOnTransitionTimeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeOnTransitionTimeWithValue:(NSNumber * _Nullable)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeOnTransitionTimeWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeOnTransitionTimeWithValue:(NSNumber * _Nullable)value
                                         params:(MTRWriteParams * _Nullable)params
                              completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeOnTransitionTimeWithValue:value params:params completion:completionHandler];
}
- (void)
    subscribeAttributeOnTransitionTimeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeOnTransitionTimeWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributeOnTransitionTimeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOnTransitionTimeWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeOffTransitionTimeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeOffTransitionTimeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeOffTransitionTimeWithValue:(NSNumber * _Nullable)value
                               completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeOffTransitionTimeWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeOffTransitionTimeWithValue:(NSNumber * _Nullable)value
                                          params:(MTRWriteParams * _Nullable)params
                               completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeOffTransitionTimeWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeOffTransitionTimeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeOffTransitionTimeWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSNumber *>(value), error);
                                          }];
}
+ (void)readAttributeOffTransitionTimeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOffTransitionTimeWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}

- (void)readAttributeDefaultMoveRateWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeDefaultMoveRateWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeDefaultMoveRateWithValue:(NSNumber * _Nullable)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeDefaultMoveRateWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeDefaultMoveRateWithValue:(NSNumber * _Nullable)value
                                        params:(MTRWriteParams * _Nullable)params
                             completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeDefaultMoveRateWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeDefaultMoveRateWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeDefaultMoveRateWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeDefaultMoveRateWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDefaultMoveRateWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (void)readAttributeStartUpCurrentLevelWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeStartUpCurrentLevelWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeStartUpCurrentLevelWithValue:(NSNumber * _Nullable)value
                                 completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeStartUpCurrentLevelWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeStartUpCurrentLevelWithValue:(NSNumber * _Nullable)value
                                            params:(MTRWriteParams * _Nullable)params
                                 completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeStartUpCurrentLevelWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeStartUpCurrentLevelWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeStartUpCurrentLevelWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSNumber *>(value), error);
                                            }];
}
+ (void)readAttributeStartUpCurrentLevelWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeStartUpCurrentLevelWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterBinaryInputBasic

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)readAttributeActiveTextWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BinaryInputBasic::Attributes::ActiveText::TypeInfo;
    return MTRReadAttribute<MTRCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeActiveTextWithValue:(NSString * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeActiveTextWithValue:(NSString * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeActiveTextWithValue:(NSString * _Nonnull)value
                                   params:(MTRWriteParams * _Nullable)params
                               completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BinaryInputBasic::Attributes::ActiveText::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = [self asCharSpan:value];

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeActiveTextWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BinaryInputBasic::Attributes::ActiveText::TypeInfo;
    MTRSubscribeAttribute<MTRCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeActiveTextWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(CharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BinaryInputBasic::Attributes::ActiveText::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeDescriptionWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BinaryInputBasic::Attributes::Description::TypeInfo;
    return MTRReadAttribute<MTRCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeDescriptionWithValue:(NSString * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeDescriptionWithValue:(NSString * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeDescriptionWithValue:(NSString * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                                completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BinaryInputBasic::Attributes::Description::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = [self asCharSpan:value];

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeDescriptionWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BinaryInputBasic::Attributes::Description::TypeInfo;
    MTRSubscribeAttribute<MTRCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeDescriptionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(CharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BinaryInputBasic::Attributes::Description::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeInactiveTextWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BinaryInputBasic::Attributes::InactiveText::TypeInfo;
    return MTRReadAttribute<MTRCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeInactiveTextWithValue:(NSString * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeInactiveTextWithValue:(NSString * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeInactiveTextWithValue:(NSString * _Nonnull)value
                                     params:(MTRWriteParams * _Nullable)params
                                 completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BinaryInputBasic::Attributes::InactiveText::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = [self asCharSpan:value];

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeInactiveTextWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BinaryInputBasic::Attributes::InactiveText::TypeInfo;
    MTRSubscribeAttribute<MTRCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeInactiveTextWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(CharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BinaryInputBasic::Attributes::InactiveText::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeOutOfServiceWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BinaryInputBasic::Attributes::OutOfService::TypeInfo;
    return MTRReadAttribute<MTRBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeOutOfServiceWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeOutOfServiceWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeOutOfServiceWithValue:(NSNumber * _Nonnull)value
                                     params:(MTRWriteParams * _Nullable)params
                                 completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BinaryInputBasic::Attributes::OutOfService::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.boolValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeOutOfServiceWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BinaryInputBasic::Attributes::OutOfService::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeOutOfServiceWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BinaryInputBasic::Attributes::OutOfService::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePolarityWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BinaryInputBasic::Attributes::Polarity::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePolarityWithParams:(MTRSubscribeParams * _Nonnull)params
                     subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                               reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BinaryInputBasic::Attributes::Polarity::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePolarityWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                        completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BinaryInputBasic::Attributes::Polarity::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePresentValueWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BinaryInputBasic::Attributes::PresentValue::TypeInfo;
    return MTRReadAttribute<MTRBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributePresentValueWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributePresentValueWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributePresentValueWithValue:(NSNumber * _Nonnull)value
                                     params:(MTRWriteParams * _Nullable)params
                                 completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BinaryInputBasic::Attributes::PresentValue::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.boolValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributePresentValueWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BinaryInputBasic::Attributes::PresentValue::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePresentValueWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BinaryInputBasic::Attributes::PresentValue::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeReliabilityWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BinaryInputBasic::Attributes::Reliability::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeReliabilityWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeReliabilityWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeReliabilityWithValue:(NSNumber * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                                completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BinaryInputBasic::Attributes::Reliability::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeReliabilityWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BinaryInputBasic::Attributes::Reliability::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeReliabilityWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BinaryInputBasic::Attributes::Reliability::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeStatusFlagsWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BinaryInputBasic::Attributes::StatusFlags::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeStatusFlagsWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BinaryInputBasic::Attributes::StatusFlags::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeStatusFlagsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BinaryInputBasic::Attributes::StatusFlags::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeApplicationTypeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BinaryInputBasic::Attributes::ApplicationType::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeApplicationTypeWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BinaryInputBasic::Attributes::ApplicationType::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeApplicationTypeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BinaryInputBasic::Attributes::ApplicationType::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BinaryInputBasic::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRBinaryInputBasicGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BinaryInputBasic::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRBinaryInputBasicGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBinaryInputBasicGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(BinaryInputBasicGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BinaryInputBasic::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BinaryInputBasic::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRBinaryInputBasicAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BinaryInputBasic::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRBinaryInputBasicAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBinaryInputBasicAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(BinaryInputBasicAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BinaryInputBasic::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BinaryInputBasic::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRBinaryInputBasicEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BinaryInputBasic::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRBinaryInputBasicEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBinaryInputBasicEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(BinaryInputBasicEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BinaryInputBasic::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BinaryInputBasic::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRBinaryInputBasicAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BinaryInputBasic::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRBinaryInputBasicAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBinaryInputBasicAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(BinaryInputBasicAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BinaryInputBasic::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BinaryInputBasic::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BinaryInputBasic::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BinaryInputBasic::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BinaryInputBasic::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BinaryInputBasic::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BinaryInputBasic::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterBinaryInputBasic (Deprecated)

- (void)readAttributeActiveTextWithCompletionHandler:(void (^)(
                                                         NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeActiveTextWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)writeAttributeActiveTextWithValue:(NSString * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeActiveTextWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeActiveTextWithValue:(NSString * _Nonnull)value
                                   params:(MTRWriteParams * _Nullable)params
                        completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeActiveTextWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeActiveTextWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeActiveTextWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSString *>(value), error);
                                   }];
}
+ (void)readAttributeActiveTextWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeActiveTextWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSString *>(value), error);
                                            }];
}

- (void)readAttributeDescriptionWithCompletionHandler:(void (^)(
                                                          NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDescriptionWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)writeAttributeDescriptionWithValue:(NSString * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeDescriptionWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeDescriptionWithValue:(NSString * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                         completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeDescriptionWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeDescriptionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeDescriptionWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSString *>(value), error);
                                    }];
}
+ (void)readAttributeDescriptionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDescriptionWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSString *>(value), error);
                                             }];
}

- (void)readAttributeInactiveTextWithCompletionHandler:(void (^)(
                                                           NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInactiveTextWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)writeAttributeInactiveTextWithValue:(NSString * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeInactiveTextWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeInactiveTextWithValue:(NSString * _Nonnull)value
                                     params:(MTRWriteParams * _Nullable)params
                          completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeInactiveTextWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeInactiveTextWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeInactiveTextWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSString *>(value), error);
                                     }];
}
+ (void)readAttributeInactiveTextWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInactiveTextWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSString *>(value), error);
                                              }];
}

- (void)readAttributeOutOfServiceWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOutOfServiceWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeOutOfServiceWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeOutOfServiceWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeOutOfServiceWithValue:(NSNumber * _Nonnull)value
                                     params:(MTRWriteParams * _Nullable)params
                          completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeOutOfServiceWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeOutOfServiceWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeOutOfServiceWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributeOutOfServiceWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOutOfServiceWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributePolarityWithCompletionHandler:(void (^)(
                                                       NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePolarityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributePolarityWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePolarityWithParams:subscribeParams
                       subscriptionEstablished:subscriptionEstablishedHandler
                                 reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                     // Cast is safe because subclass does not add any selectors.
                                     reportHandler(static_cast<NSNumber *>(value), error);
                                 }];
}
+ (void)readAttributePolarityWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePolarityWithClusterStateCache:attributeCacheContainer.realContainer
                                            endpoint:endpoint
                                               queue:queue
                                          completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              completionHandler(static_cast<NSNumber *>(value), error);
                                          }];
}

- (void)readAttributePresentValueWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePresentValueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributePresentValueWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributePresentValueWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributePresentValueWithValue:(NSNumber * _Nonnull)value
                                     params:(MTRWriteParams * _Nullable)params
                          completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributePresentValueWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributePresentValueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePresentValueWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributePresentValueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePresentValueWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributeReliabilityWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeReliabilityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeReliabilityWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeReliabilityWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeReliabilityWithValue:(NSNumber * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                         completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeReliabilityWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeReliabilityWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeReliabilityWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSNumber *>(value), error);
                                    }];
}
+ (void)readAttributeReliabilityWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeReliabilityWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                             }];
}

- (void)readAttributeStatusFlagsWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeStatusFlagsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeStatusFlagsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeStatusFlagsWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSNumber *>(value), error);
                                    }];
}
+ (void)readAttributeStatusFlagsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeStatusFlagsWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                             }];
}

- (void)readAttributeApplicationTypeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeApplicationTypeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeApplicationTypeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeApplicationTypeWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeApplicationTypeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeApplicationTypeWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterDescriptor

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)readAttributeDeviceTypeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Descriptor::Attributes::DeviceTypeList::TypeInfo;
    return MTRReadAttribute<MTRDescriptorDeviceTypeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeDeviceTypeListWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Descriptor::Attributes::DeviceTypeList::TypeInfo;
    MTRSubscribeAttribute<MTRDescriptorDeviceTypeListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeDeviceTypeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRDescriptorDeviceTypeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(DescriptorDeviceTypeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Descriptor::Attributes::DeviceTypeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeServerListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Descriptor::Attributes::ServerList::TypeInfo;
    return MTRReadAttribute<MTRDescriptorServerListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeServerListWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Descriptor::Attributes::ServerList::TypeInfo;
    MTRSubscribeAttribute<MTRDescriptorServerListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeServerListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRDescriptorServerListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(DescriptorServerListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Descriptor::Attributes::ServerList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClientListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Descriptor::Attributes::ClientList::TypeInfo;
    return MTRReadAttribute<MTRDescriptorClientListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClientListWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Descriptor::Attributes::ClientList::TypeInfo;
    MTRSubscribeAttribute<MTRDescriptorClientListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClientListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRDescriptorClientListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(DescriptorClientListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Descriptor::Attributes::ClientList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePartsListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Descriptor::Attributes::PartsList::TypeInfo;
    return MTRReadAttribute<MTRDescriptorPartsListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePartsListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Descriptor::Attributes::PartsList::TypeInfo;
    MTRSubscribeAttribute<MTRDescriptorPartsListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePartsListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRDescriptorPartsListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(DescriptorPartsListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Descriptor::Attributes::PartsList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Descriptor::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRDescriptorGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Descriptor::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRDescriptorGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRDescriptorGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(DescriptorGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Descriptor::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Descriptor::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRDescriptorAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Descriptor::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRDescriptorAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRDescriptorAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(DescriptorAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Descriptor::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Descriptor::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRDescriptorEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Descriptor::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRDescriptorEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRDescriptorEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(DescriptorEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Descriptor::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Descriptor::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRDescriptorAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Descriptor::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRDescriptorAttributeListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRDescriptorAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(DescriptorAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Descriptor::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Descriptor::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Descriptor::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Descriptor::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Descriptor::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Descriptor::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Descriptor::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterDescriptor (Deprecated)

- (void)readAttributeDeviceListWithCompletionHandler:(void (^)(
                                                         NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDeviceTypeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeDeviceListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeDeviceTypeListWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSArray *>(value), error);
                                       }];
}
+ (void)readAttributeDeviceListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDeviceTypeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSArray *>(value), error);
                                                }];
}

- (void)readAttributeServerListWithCompletionHandler:(void (^)(
                                                         NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeServerListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeServerListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeServerListWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSArray *>(value), error);
                                   }];
}
+ (void)readAttributeServerListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeServerListWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSArray *>(value), error);
                                            }];
}

- (void)readAttributeClientListWithCompletionHandler:(void (^)(
                                                         NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClientListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeClientListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClientListWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSArray *>(value), error);
                                   }];
}
+ (void)readAttributeClientListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClientListWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSArray *>(value), error);
                                            }];
}

- (void)readAttributePartsListWithCompletionHandler:(void (^)(
                                                        NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePartsListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributePartsListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePartsListWithParams:subscribeParams
                        subscriptionEstablished:subscriptionEstablishedHandler
                                  reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                      // Cast is safe because subclass does not add any selectors.
                                      reportHandler(static_cast<NSArray *>(value), error);
                                  }];
}
+ (void)readAttributePartsListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePartsListWithClusterStateCache:attributeCacheContainer.realContainer
                                             endpoint:endpoint
                                                queue:queue
                                           completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               completionHandler(static_cast<NSArray *>(value), error);
                                           }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterBinding

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)readAttributeBindingWithParams:(MTRReadParams * _Nullable)params
                            completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{ // Make a copy of params before we go async.
    params = [params copy];
    using TypeInfo = Binding::Attributes::Binding::TypeInfo;
    return MTRReadAttribute<MTRBindingBindingListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeBindingWithValue:(NSArray * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeBindingWithValue:(NSArray * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeBindingWithValue:(NSArray * _Nonnull)value
                                params:(MTRWriteParams * _Nullable)params
                            completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Binding::Attributes::Binding::TypeInfo;
            TypeInfo::Type cppValue;
            {
                using ListType_0 = std::remove_reference_t<decltype(cppValue)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (value.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(value.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < value.count; ++i_0) {
                        if (![value[i_0] isKindOfClass:[MTRBindingClusterTargetStruct class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (MTRBindingClusterTargetStruct *) value[i_0];
                        if (element_0.node != nil) {
                            auto & definedValue_2 = listHolder_0->mList[i_0].node.Emplace();
                            definedValue_2 = element_0.node.unsignedLongLongValue;
                        }
                        if (element_0.group != nil) {
                            auto & definedValue_2 = listHolder_0->mList[i_0].group.Emplace();
                            definedValue_2 = element_0.group.unsignedShortValue;
                        }
                        if (element_0.endpoint != nil) {
                            auto & definedValue_2 = listHolder_0->mList[i_0].endpoint.Emplace();
                            definedValue_2 = element_0.endpoint.unsignedShortValue;
                        }
                        if (element_0.cluster != nil) {
                            auto & definedValue_2 = listHolder_0->mList[i_0].cluster.Emplace();
                            definedValue_2 = element_0.cluster.unsignedIntValue;
                        }
                        listHolder_0->mList[i_0].fabricIndex = element_0.fabricIndex.unsignedCharValue;
                    }
                    cppValue = ListType_0(listHolder_0->mList, value.count);
                } else {
                    cppValue = ListType_0();
                }
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeBindingWithParams:(MTRSubscribeParams * _Nonnull)params
                    subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                              reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Binding::Attributes::Binding::TypeInfo;
    MTRSubscribeAttribute<MTRBindingBindingListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeBindingWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                       completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBindingBindingListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BindingBindingListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Binding::Attributes::Binding::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Binding::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRBindingGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Binding::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRBindingGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBindingGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(BindingGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Binding::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Binding::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRBindingAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Binding::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRBindingAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBindingAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(BindingAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Binding::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Binding::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRBindingEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Binding::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRBindingEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBindingEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BindingEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Binding::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Binding::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRBindingAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Binding::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRBindingAttributeListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBindingAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BindingAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Binding::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Binding::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Binding::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Binding::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Binding::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Binding::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Binding::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterBinding (Deprecated)

- (void)readAttributeBindingWithParams:(MTRReadParams * _Nullable)params
                     completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBindingWithParams:params
                              completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                  // Cast is safe because subclass does not add any selectors.
                                  completionHandler(static_cast<NSArray *>(value), error);
                              }];
}
- (void)writeAttributeBindingWithValue:(NSArray * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeBindingWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeBindingWithValue:(NSArray * _Nonnull)value
                                params:(MTRWriteParams * _Nullable)params
                     completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeBindingWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeBindingWithMinInterval:(NSNumber * _Nonnull)minInterval
                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                          params:(MTRSubscribeParams * _Nullable)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                   reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeBindingWithParams:subscribeParams
                      subscriptionEstablished:subscriptionEstablishedHandler
                                reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                    // Cast is safe because subclass does not add any selectors.
                                    reportHandler(static_cast<NSArray *>(value), error);
                                }];
}
+ (void)readAttributeBindingWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                      endpoint:(NSNumber *)endpoint
                                         queue:(dispatch_queue_t)queue
                             completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBindingWithClusterStateCache:attributeCacheContainer.realContainer
                                           endpoint:endpoint
                                              queue:queue
                                         completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             completionHandler(static_cast<NSArray *>(value), error);
                                         }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterAccessControl

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)readAttributeACLWithParams:(MTRReadParams * _Nullable)params
                        completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{ // Make a copy of params before we go async.
    params = [params copy];
    using TypeInfo = AccessControl::Attributes::Acl::TypeInfo;
    return MTRReadAttribute<MTRAccessControlACLListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeACLWithValue:(NSArray * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeACLWithValue:(NSArray * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeACLWithValue:(NSArray * _Nonnull)value
                            params:(MTRWriteParams * _Nullable)params
                        completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = AccessControl::Attributes::Acl::TypeInfo;
            TypeInfo::Type cppValue;
            {
                using ListType_0 = std::remove_reference_t<decltype(cppValue)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (value.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(value.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < value.count; ++i_0) {
                        if (![value[i_0] isKindOfClass:[MTRAccessControlClusterAccessControlEntryStruct class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (MTRAccessControlClusterAccessControlEntryStruct *) value[i_0];
                        listHolder_0->mList[i_0].privilege
                            = static_cast<std::remove_reference_t<decltype(listHolder_0->mList[i_0].privilege)>>(
                                element_0.privilege.unsignedCharValue);
                        listHolder_0->mList[i_0].authMode
                            = static_cast<std::remove_reference_t<decltype(listHolder_0->mList[i_0].authMode)>>(
                                element_0.authMode.unsignedCharValue);
                        if (element_0.subjects == nil) {
                            listHolder_0->mList[i_0].subjects.SetNull();
                        } else {
                            auto & nonNullValue_2 = listHolder_0->mList[i_0].subjects.SetNonNull();
                            {
                                using ListType_3 = std::remove_reference_t<decltype(nonNullValue_2)>;
                                using ListMemberType_3 = ListMemberTypeGetter<ListType_3>::Type;
                                if (element_0.subjects.count != 0) {
                                    auto * listHolder_3 = new ListHolder<ListMemberType_3>(element_0.subjects.count);
                                    if (listHolder_3 == nullptr || listHolder_3->mList == nullptr) {
                                        return CHIP_ERROR_INVALID_ARGUMENT;
                                    }
                                    listFreer.add(listHolder_3);
                                    for (size_t i_3 = 0; i_3 < element_0.subjects.count; ++i_3) {
                                        if (![element_0.subjects[i_3] isKindOfClass:[NSNumber class]]) {
                                            // Wrong kind of value.
                                            return CHIP_ERROR_INVALID_ARGUMENT;
                                        }
                                        auto element_3 = (NSNumber *) element_0.subjects[i_3];
                                        listHolder_3->mList[i_3] = element_3.unsignedLongLongValue;
                                    }
                                    nonNullValue_2 = ListType_3(listHolder_3->mList, element_0.subjects.count);
                                } else {
                                    nonNullValue_2 = ListType_3();
                                }
                            }
                        }
                        if (element_0.targets == nil) {
                            listHolder_0->mList[i_0].targets.SetNull();
                        } else {
                            auto & nonNullValue_2 = listHolder_0->mList[i_0].targets.SetNonNull();
                            {
                                using ListType_3 = std::remove_reference_t<decltype(nonNullValue_2)>;
                                using ListMemberType_3 = ListMemberTypeGetter<ListType_3>::Type;
                                if (element_0.targets.count != 0) {
                                    auto * listHolder_3 = new ListHolder<ListMemberType_3>(element_0.targets.count);
                                    if (listHolder_3 == nullptr || listHolder_3->mList == nullptr) {
                                        return CHIP_ERROR_INVALID_ARGUMENT;
                                    }
                                    listFreer.add(listHolder_3);
                                    for (size_t i_3 = 0; i_3 < element_0.targets.count; ++i_3) {
                                        if (![element_0.targets[i_3] isKindOfClass:[MTRAccessControlClusterTarget class]]) {
                                            // Wrong kind of value.
                                            return CHIP_ERROR_INVALID_ARGUMENT;
                                        }
                                        auto element_3 = (MTRAccessControlClusterTarget *) element_0.targets[i_3];
                                        if (element_3.cluster == nil) {
                                            listHolder_3->mList[i_3].cluster.SetNull();
                                        } else {
                                            auto & nonNullValue_5 = listHolder_3->mList[i_3].cluster.SetNonNull();
                                            nonNullValue_5 = element_3.cluster.unsignedIntValue;
                                        }
                                        if (element_3.endpoint == nil) {
                                            listHolder_3->mList[i_3].endpoint.SetNull();
                                        } else {
                                            auto & nonNullValue_5 = listHolder_3->mList[i_3].endpoint.SetNonNull();
                                            nonNullValue_5 = element_3.endpoint.unsignedShortValue;
                                        }
                                        if (element_3.deviceType == nil) {
                                            listHolder_3->mList[i_3].deviceType.SetNull();
                                        } else {
                                            auto & nonNullValue_5 = listHolder_3->mList[i_3].deviceType.SetNonNull();
                                            nonNullValue_5 = element_3.deviceType.unsignedIntValue;
                                        }
                                    }
                                    nonNullValue_2 = ListType_3(listHolder_3->mList, element_0.targets.count);
                                } else {
                                    nonNullValue_2 = ListType_3();
                                }
                            }
                        }
                        listHolder_0->mList[i_0].fabricIndex = element_0.fabricIndex.unsignedCharValue;
                    }
                    cppValue = ListType_0(listHolder_0->mList, value.count);
                } else {
                    cppValue = ListType_0();
                }
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeACLWithParams:(MTRSubscribeParams * _Nonnull)params
                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                          reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = AccessControl::Attributes::Acl::TypeInfo;
    MTRSubscribeAttribute<MTRAccessControlACLListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeACLWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                                   completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRAccessControlACLListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(AccessControlACLListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AccessControl::Attributes::Acl::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeExtensionWithParams:(MTRReadParams * _Nullable)params
                              completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{ // Make a copy of params before we go async.
    params = [params copy];
    using TypeInfo = AccessControl::Attributes::Extension::TypeInfo;
    return MTRReadAttribute<MTRAccessControlExtensionListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeExtensionWithValue:(NSArray * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeExtensionWithValue:(NSArray * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeExtensionWithValue:(NSArray * _Nonnull)value
                                  params:(MTRWriteParams * _Nullable)params
                              completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = AccessControl::Attributes::Extension::TypeInfo;
            TypeInfo::Type cppValue;
            {
                using ListType_0 = std::remove_reference_t<decltype(cppValue)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (value.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(value.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < value.count; ++i_0) {
                        if (![value[i_0] isKindOfClass:[MTRAccessControlClusterAccessControlExtensionStruct class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (MTRAccessControlClusterAccessControlExtensionStruct *) value[i_0];
                        listHolder_0->mList[i_0].data = [self asByteSpan:element_0.data];
                        listHolder_0->mList[i_0].fabricIndex = element_0.fabricIndex.unsignedCharValue;
                    }
                    cppValue = ListType_0(listHolder_0->mList, value.count);
                } else {
                    cppValue = ListType_0();
                }
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeExtensionWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = AccessControl::Attributes::Extension::TypeInfo;
    MTRSubscribeAttribute<MTRAccessControlExtensionListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeExtensionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRAccessControlExtensionListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(AccessControlExtensionListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AccessControl::Attributes::Extension::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSubjectsPerAccessControlEntryWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = AccessControl::Attributes::SubjectsPerAccessControlEntry::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeSubjectsPerAccessControlEntryWithParams:(MTRSubscribeParams * _Nonnull)params
                                          subscriptionEstablished:
                                              (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                    reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))reportHandler
{
    using TypeInfo = AccessControl::Attributes::SubjectsPerAccessControlEntry::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeSubjectsPerAccessControlEntryWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                               endpoint:(NSNumber *)endpoint
                                                                  queue:(dispatch_queue_t)queue
                                                             completion:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AccessControl::Attributes::SubjectsPerAccessControlEntry::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeTargetsPerAccessControlEntryWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = AccessControl::Attributes::TargetsPerAccessControlEntry::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeTargetsPerAccessControlEntryWithParams:(MTRSubscribeParams * _Nonnull)params
                                         subscriptionEstablished:
                                             (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                   reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))reportHandler
{
    using TypeInfo = AccessControl::Attributes::TargetsPerAccessControlEntry::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeTargetsPerAccessControlEntryWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                              endpoint:(NSNumber *)endpoint
                                                                 queue:(dispatch_queue_t)queue
                                                            completion:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AccessControl::Attributes::TargetsPerAccessControlEntry::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAccessControlEntriesPerFabricWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = AccessControl::Attributes::AccessControlEntriesPerFabric::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAccessControlEntriesPerFabricWithParams:(MTRSubscribeParams * _Nonnull)params
                                          subscriptionEstablished:
                                              (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                    reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))reportHandler
{
    using TypeInfo = AccessControl::Attributes::AccessControlEntriesPerFabric::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAccessControlEntriesPerFabricWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                               endpoint:(NSNumber *)endpoint
                                                                  queue:(dispatch_queue_t)queue
                                                             completion:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AccessControl::Attributes::AccessControlEntriesPerFabric::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = AccessControl::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRAccessControlGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = AccessControl::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRAccessControlGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRAccessControlGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(AccessControlGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AccessControl::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = AccessControl::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRAccessControlAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = AccessControl::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRAccessControlAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRAccessControlAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(AccessControlAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AccessControl::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = AccessControl::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRAccessControlEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = AccessControl::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRAccessControlEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRAccessControlEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(AccessControlEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AccessControl::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = AccessControl::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRAccessControlAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = AccessControl::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRAccessControlAttributeListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRAccessControlAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(AccessControlAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AccessControl::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = AccessControl::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = AccessControl::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AccessControl::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = AccessControl::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = AccessControl::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AccessControl::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterAccessControl (Deprecated)

- (void)readAttributeAclWithParams:(MTRReadParams * _Nullable)params
                 completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeACLWithParams:params
                          completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                              // Cast is safe because subclass does not add any selectors.
                              completionHandler(static_cast<NSArray *>(value), error);
                          }];
}
- (void)writeAttributeAclWithValue:(NSArray * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeACLWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeAclWithValue:(NSArray * _Nonnull)value
                            params:(MTRWriteParams * _Nullable)params
                 completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeACLWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeAclWithMinInterval:(NSNumber * _Nonnull)minInterval
                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                      params:(MTRSubscribeParams * _Nullable)params
                     subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                               reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeACLWithParams:subscribeParams
                  subscriptionEstablished:subscriptionEstablishedHandler
                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                // Cast is safe because subclass does not add any selectors.
                                reportHandler(static_cast<NSArray *>(value), error);
                            }];
}
+ (void)readAttributeAclWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                  endpoint:(NSNumber *)endpoint
                                     queue:(dispatch_queue_t)queue
                         completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeACLWithClusterStateCache:attributeCacheContainer.realContainer
                                       endpoint:endpoint
                                          queue:queue
                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         completionHandler(static_cast<NSArray *>(value), error);
                                     }];
}

- (void)readAttributeExtensionWithParams:(MTRReadParams * _Nullable)params
                       completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeExtensionWithParams:params
                                completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                    // Cast is safe because subclass does not add any selectors.
                                    completionHandler(static_cast<NSArray *>(value), error);
                                }];
}
- (void)writeAttributeExtensionWithValue:(NSArray * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeExtensionWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeExtensionWithValue:(NSArray * _Nonnull)value
                                  params:(MTRWriteParams * _Nullable)params
                       completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeExtensionWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeExtensionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeExtensionWithParams:subscribeParams
                        subscriptionEstablished:subscriptionEstablishedHandler
                                  reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                      // Cast is safe because subclass does not add any selectors.
                                      reportHandler(static_cast<NSArray *>(value), error);
                                  }];
}
+ (void)readAttributeExtensionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeExtensionWithClusterStateCache:attributeCacheContainer.realContainer
                                             endpoint:endpoint
                                                queue:queue
                                           completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               completionHandler(static_cast<NSArray *>(value), error);
                                           }];
}

- (void)readAttributeSubjectsPerAccessControlEntryWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))completionHandler
{
    [self readAttributeSubjectsPerAccessControlEntryWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeSubjectsPerAccessControlEntryWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                params:(MTRSubscribeParams * _Nullable)params
                                               subscriptionEstablished:
                                                   (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                         reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeSubjectsPerAccessControlEntryWithParams:subscribeParams
                                            subscriptionEstablished:subscriptionEstablishedHandler
                                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          reportHandler(static_cast<NSNumber *>(value), error);
                                                      }];
}
+ (void)readAttributeSubjectsPerAccessControlEntryWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                            endpoint:(NSNumber *)endpoint
                                                               queue:(dispatch_queue_t)queue
                                                   completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    [self readAttributeSubjectsPerAccessControlEntryWithClusterStateCache:attributeCacheContainer.realContainer
                                                                 endpoint:endpoint
                                                                    queue:queue
                                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                   // Cast is safe because subclass does not add any selectors.
                                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                                               }];
}

- (void)readAttributeTargetsPerAccessControlEntryWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completionHandler
{
    [self readAttributeTargetsPerAccessControlEntryWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeTargetsPerAccessControlEntryWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                                               params:(MTRSubscribeParams * _Nullable)params
                                              subscriptionEstablished:
                                                  (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                        reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeTargetsPerAccessControlEntryWithParams:subscribeParams
                                           subscriptionEstablished:subscriptionEstablishedHandler
                                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         reportHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}
+ (void)readAttributeTargetsPerAccessControlEntryWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                           endpoint:(NSNumber *)endpoint
                                                              queue:(dispatch_queue_t)queue
                                                  completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    [self readAttributeTargetsPerAccessControlEntryWithClusterStateCache:attributeCacheContainer.realContainer
                                                                endpoint:endpoint
                                                                   queue:queue
                                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                  // Cast is safe because subclass does not add any selectors.
                                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                                              }];
}

- (void)readAttributeAccessControlEntriesPerFabricWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))completionHandler
{
    [self readAttributeAccessControlEntriesPerFabricWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeAccessControlEntriesPerFabricWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                params:(MTRSubscribeParams * _Nullable)params
                                               subscriptionEstablished:
                                                   (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                         reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAccessControlEntriesPerFabricWithParams:subscribeParams
                                            subscriptionEstablished:subscriptionEstablishedHandler
                                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          reportHandler(static_cast<NSNumber *>(value), error);
                                                      }];
}
+ (void)readAttributeAccessControlEntriesPerFabricWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                            endpoint:(NSNumber *)endpoint
                                                               queue:(dispatch_queue_t)queue
                                                   completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    [self readAttributeAccessControlEntriesPerFabricWithClusterStateCache:attributeCacheContainer.realContainer
                                                                 endpoint:endpoint
                                                                    queue:queue
                                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                   // Cast is safe because subclass does not add any selectors.
                                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                                               }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterActions

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)instantActionWithParams:(MTRActionsClusterInstantActionParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            Actions::Commands::InstantAction::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.actionID = params.actionID.unsignedShortValue;
            if (params.invokeID != nil) {
                auto & definedValue_0 = request.invokeID.Emplace();
                definedValue_0 = params.invokeID.unsignedIntValue;
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)instantActionWithTransitionWithParams:(MTRActionsClusterInstantActionWithTransitionParams *)params
                                   completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            Actions::Commands::InstantActionWithTransition::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.actionID = params.actionID.unsignedShortValue;
            if (params.invokeID != nil) {
                auto & definedValue_0 = request.invokeID.Emplace();
                definedValue_0 = params.invokeID.unsignedIntValue;
            }
            request.transitionTime = params.transitionTime.unsignedShortValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)startActionWithParams:(MTRActionsClusterStartActionParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            Actions::Commands::StartAction::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.actionID = params.actionID.unsignedShortValue;
            if (params.invokeID != nil) {
                auto & definedValue_0 = request.invokeID.Emplace();
                definedValue_0 = params.invokeID.unsignedIntValue;
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)startActionWithDurationWithParams:(MTRActionsClusterStartActionWithDurationParams *)params
                               completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            Actions::Commands::StartActionWithDuration::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.actionID = params.actionID.unsignedShortValue;
            if (params.invokeID != nil) {
                auto & definedValue_0 = request.invokeID.Emplace();
                definedValue_0 = params.invokeID.unsignedIntValue;
            }
            request.duration = params.duration.unsignedIntValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)stopActionWithParams:(MTRActionsClusterStopActionParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            Actions::Commands::StopAction::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.actionID = params.actionID.unsignedShortValue;
            if (params.invokeID != nil) {
                auto & definedValue_0 = request.invokeID.Emplace();
                definedValue_0 = params.invokeID.unsignedIntValue;
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)pauseActionWithParams:(MTRActionsClusterPauseActionParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            Actions::Commands::PauseAction::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.actionID = params.actionID.unsignedShortValue;
            if (params.invokeID != nil) {
                auto & definedValue_0 = request.invokeID.Emplace();
                definedValue_0 = params.invokeID.unsignedIntValue;
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)pauseActionWithDurationWithParams:(MTRActionsClusterPauseActionWithDurationParams *)params
                               completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            Actions::Commands::PauseActionWithDuration::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.actionID = params.actionID.unsignedShortValue;
            if (params.invokeID != nil) {
                auto & definedValue_0 = request.invokeID.Emplace();
                definedValue_0 = params.invokeID.unsignedIntValue;
            }
            request.duration = params.duration.unsignedIntValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)resumeActionWithParams:(MTRActionsClusterResumeActionParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            Actions::Commands::ResumeAction::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.actionID = params.actionID.unsignedShortValue;
            if (params.invokeID != nil) {
                auto & definedValue_0 = request.invokeID.Emplace();
                definedValue_0 = params.invokeID.unsignedIntValue;
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)enableActionWithParams:(MTRActionsClusterEnableActionParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            Actions::Commands::EnableAction::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.actionID = params.actionID.unsignedShortValue;
            if (params.invokeID != nil) {
                auto & definedValue_0 = request.invokeID.Emplace();
                definedValue_0 = params.invokeID.unsignedIntValue;
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)enableActionWithDurationWithParams:(MTRActionsClusterEnableActionWithDurationParams *)params
                                completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            Actions::Commands::EnableActionWithDuration::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.actionID = params.actionID.unsignedShortValue;
            if (params.invokeID != nil) {
                auto & definedValue_0 = request.invokeID.Emplace();
                definedValue_0 = params.invokeID.unsignedIntValue;
            }
            request.duration = params.duration.unsignedIntValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)disableActionWithParams:(MTRActionsClusterDisableActionParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            Actions::Commands::DisableAction::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.actionID = params.actionID.unsignedShortValue;
            if (params.invokeID != nil) {
                auto & definedValue_0 = request.invokeID.Emplace();
                definedValue_0 = params.invokeID.unsignedIntValue;
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)disableActionWithDurationWithParams:(MTRActionsClusterDisableActionWithDurationParams *)params
                                 completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            Actions::Commands::DisableActionWithDuration::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.actionID = params.actionID.unsignedShortValue;
            if (params.invokeID != nil) {
                auto & definedValue_0 = request.invokeID.Emplace();
                definedValue_0 = params.invokeID.unsignedIntValue;
            }
            request.duration = params.duration.unsignedIntValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeActionListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Actions::Attributes::ActionList::TypeInfo;
    return MTRReadAttribute<MTRActionsActionListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeActionListWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Actions::Attributes::ActionList::TypeInfo;
    MTRSubscribeAttribute<MTRActionsActionListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeActionListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRActionsActionListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(ActionsActionListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Actions::Attributes::ActionList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEndpointListsWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Actions::Attributes::EndpointLists::TypeInfo;
    return MTRReadAttribute<MTRActionsEndpointListsListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEndpointListsWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Actions::Attributes::EndpointLists::TypeInfo;
    MTRSubscribeAttribute<MTRActionsEndpointListsListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEndpointListsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRActionsEndpointListsListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(ActionsEndpointListsListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Actions::Attributes::EndpointLists::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSetupURLWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Actions::Attributes::SetupURL::TypeInfo;
    return MTRReadAttribute<MTRCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeSetupURLWithParams:(MTRSubscribeParams * _Nonnull)params
                     subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                               reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Actions::Attributes::SetupURL::TypeInfo;
    MTRSubscribeAttribute<MTRCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeSetupURLWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                        completion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(CharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Actions::Attributes::SetupURL::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Actions::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRActionsGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Actions::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRActionsGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRActionsGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ActionsGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Actions::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Actions::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRActionsAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Actions::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRActionsAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRActionsAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ActionsAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Actions::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Actions::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRActionsEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Actions::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRActionsEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRActionsEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(ActionsEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Actions::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Actions::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRActionsAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Actions::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRActionsAttributeListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRActionsAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(ActionsAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Actions::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Actions::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Actions::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Actions::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Actions::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Actions::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Actions::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterActions (Deprecated)

- (void)instantActionWithParams:(MTRActionsClusterInstantActionParams *)params
              completionHandler:(MTRStatusCompletion)completionHandler
{
    [self instantActionWithParams:params completion:completionHandler];
}
- (void)instantActionWithTransitionWithParams:(MTRActionsClusterInstantActionWithTransitionParams *)params
                            completionHandler:(MTRStatusCompletion)completionHandler
{
    [self instantActionWithTransitionWithParams:params completion:completionHandler];
}
- (void)startActionWithParams:(MTRActionsClusterStartActionParams *)params completionHandler:(MTRStatusCompletion)completionHandler
{
    [self startActionWithParams:params completion:completionHandler];
}
- (void)startActionWithDurationWithParams:(MTRActionsClusterStartActionWithDurationParams *)params
                        completionHandler:(MTRStatusCompletion)completionHandler
{
    [self startActionWithDurationWithParams:params completion:completionHandler];
}
- (void)stopActionWithParams:(MTRActionsClusterStopActionParams *)params completionHandler:(MTRStatusCompletion)completionHandler
{
    [self stopActionWithParams:params completion:completionHandler];
}
- (void)pauseActionWithParams:(MTRActionsClusterPauseActionParams *)params completionHandler:(MTRStatusCompletion)completionHandler
{
    [self pauseActionWithParams:params completion:completionHandler];
}
- (void)pauseActionWithDurationWithParams:(MTRActionsClusterPauseActionWithDurationParams *)params
                        completionHandler:(MTRStatusCompletion)completionHandler
{
    [self pauseActionWithDurationWithParams:params completion:completionHandler];
}
- (void)resumeActionWithParams:(MTRActionsClusterResumeActionParams *)params
             completionHandler:(MTRStatusCompletion)completionHandler
{
    [self resumeActionWithParams:params completion:completionHandler];
}
- (void)enableActionWithParams:(MTRActionsClusterEnableActionParams *)params
             completionHandler:(MTRStatusCompletion)completionHandler
{
    [self enableActionWithParams:params completion:completionHandler];
}
- (void)enableActionWithDurationWithParams:(MTRActionsClusterEnableActionWithDurationParams *)params
                         completionHandler:(MTRStatusCompletion)completionHandler
{
    [self enableActionWithDurationWithParams:params completion:completionHandler];
}
- (void)disableActionWithParams:(MTRActionsClusterDisableActionParams *)params
              completionHandler:(MTRStatusCompletion)completionHandler
{
    [self disableActionWithParams:params completion:completionHandler];
}
- (void)disableActionWithDurationWithParams:(MTRActionsClusterDisableActionWithDurationParams *)params
                          completionHandler:(MTRStatusCompletion)completionHandler
{
    [self disableActionWithDurationWithParams:params completion:completionHandler];
}

- (void)readAttributeActionListWithCompletionHandler:(void (^)(
                                                         NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeActionListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeActionListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeActionListWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSArray *>(value), error);
                                   }];
}
+ (void)readAttributeActionListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeActionListWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSArray *>(value), error);
                                            }];
}

- (void)readAttributeEndpointListsWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeEndpointListsWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeEndpointListsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeEndpointListsWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeEndpointListsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeEndpointListsWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeSetupURLWithCompletionHandler:(void (^)(
                                                       NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSetupURLWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)subscribeAttributeSetupURLWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeSetupURLWithParams:subscribeParams
                       subscriptionEstablished:subscriptionEstablishedHandler
                                 reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                     // Cast is safe because subclass does not add any selectors.
                                     reportHandler(static_cast<NSString *>(value), error);
                                 }];
}
+ (void)readAttributeSetupURLWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSetupURLWithClusterStateCache:attributeCacheContainer.realContainer
                                            endpoint:endpoint
                                               queue:queue
                                          completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              completionHandler(static_cast<NSString *>(value), error);
                                          }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterBasicInformation

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)mfgSpecificPingWithCompletion:(MTRStatusCompletion)completion
{
    [self mfgSpecificPingWithParams:nil completion:completion];
}
- (void)mfgSpecificPingWithParams:(MTRBasicClusterMfgSpecificPingParams * _Nullable)params
                       completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            BasicInformation::Commands::MfgSpecificPing::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeDataModelRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BasicInformation::Attributes::DataModelRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeDataModelRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BasicInformation::Attributes::DataModelRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeDataModelRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BasicInformation::Attributes::DataModelRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeVendorNameWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BasicInformation::Attributes::VendorName::TypeInfo;
    return MTRReadAttribute<MTRCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeVendorNameWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BasicInformation::Attributes::VendorName::TypeInfo;
    MTRSubscribeAttribute<MTRCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeVendorNameWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(CharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BasicInformation::Attributes::VendorName::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeVendorIDWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BasicInformation::Attributes::VendorID::TypeInfo;
    return MTRReadAttribute<MTRVendorIdAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeVendorIDWithParams:(MTRSubscribeParams * _Nonnull)params
                     subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                               reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BasicInformation::Attributes::VendorID::TypeInfo;
    MTRSubscribeAttribute<MTRVendorIdAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeVendorIDWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                        completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRVendorIdAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(VendorIdAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BasicInformation::Attributes::VendorID::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeProductNameWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BasicInformation::Attributes::ProductName::TypeInfo;
    return MTRReadAttribute<MTRCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeProductNameWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BasicInformation::Attributes::ProductName::TypeInfo;
    MTRSubscribeAttribute<MTRCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeProductNameWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(CharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BasicInformation::Attributes::ProductName::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeProductIDWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BasicInformation::Attributes::ProductID::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeProductIDWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BasicInformation::Attributes::ProductID::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeProductIDWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BasicInformation::Attributes::ProductID::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNodeLabelWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BasicInformation::Attributes::NodeLabel::TypeInfo;
    return MTRReadAttribute<MTRCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeNodeLabelWithValue:(NSString * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeNodeLabelWithValue:(NSString * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeNodeLabelWithValue:(NSString * _Nonnull)value
                                  params:(MTRWriteParams * _Nullable)params
                              completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BasicInformation::Attributes::NodeLabel::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = [self asCharSpan:value];

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeNodeLabelWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BasicInformation::Attributes::NodeLabel::TypeInfo;
    MTRSubscribeAttribute<MTRCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNodeLabelWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(CharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BasicInformation::Attributes::NodeLabel::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeLocationWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BasicInformation::Attributes::Location::TypeInfo;
    return MTRReadAttribute<MTRCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeLocationWithValue:(NSString * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeLocationWithValue:(NSString * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeLocationWithValue:(NSString * _Nonnull)value
                                 params:(MTRWriteParams * _Nullable)params
                             completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BasicInformation::Attributes::Location::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = [self asCharSpan:value];

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeLocationWithParams:(MTRSubscribeParams * _Nonnull)params
                     subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                               reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BasicInformation::Attributes::Location::TypeInfo;
    MTRSubscribeAttribute<MTRCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeLocationWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                        completion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(CharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BasicInformation::Attributes::Location::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeHardwareVersionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BasicInformation::Attributes::HardwareVersion::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeHardwareVersionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BasicInformation::Attributes::HardwareVersion::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeHardwareVersionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BasicInformation::Attributes::HardwareVersion::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeHardwareVersionStringWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BasicInformation::Attributes::HardwareVersionString::TypeInfo;
    return MTRReadAttribute<MTRCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeHardwareVersionStringWithParams:(MTRSubscribeParams * _Nonnull)params
                                  subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                            reportHandler:
                                                (void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BasicInformation::Attributes::HardwareVersionString::TypeInfo;
    MTRSubscribeAttribute<MTRCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeHardwareVersionStringWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                                     completion:
                                                         (void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(CharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BasicInformation::Attributes::HardwareVersionString::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSoftwareVersionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BasicInformation::Attributes::SoftwareVersion::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeSoftwareVersionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BasicInformation::Attributes::SoftwareVersion::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeSoftwareVersionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BasicInformation::Attributes::SoftwareVersion::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSoftwareVersionStringWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BasicInformation::Attributes::SoftwareVersionString::TypeInfo;
    return MTRReadAttribute<MTRCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeSoftwareVersionStringWithParams:(MTRSubscribeParams * _Nonnull)params
                                  subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                            reportHandler:
                                                (void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BasicInformation::Attributes::SoftwareVersionString::TypeInfo;
    MTRSubscribeAttribute<MTRCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeSoftwareVersionStringWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                                     completion:
                                                         (void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(CharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BasicInformation::Attributes::SoftwareVersionString::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeManufacturingDateWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BasicInformation::Attributes::ManufacturingDate::TypeInfo;
    return MTRReadAttribute<MTRCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeManufacturingDateWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BasicInformation::Attributes::ManufacturingDate::TypeInfo;
    MTRSubscribeAttribute<MTRCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeManufacturingDateWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(CharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BasicInformation::Attributes::ManufacturingDate::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePartNumberWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BasicInformation::Attributes::PartNumber::TypeInfo;
    return MTRReadAttribute<MTRCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePartNumberWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BasicInformation::Attributes::PartNumber::TypeInfo;
    MTRSubscribeAttribute<MTRCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePartNumberWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(CharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BasicInformation::Attributes::PartNumber::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeProductURLWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BasicInformation::Attributes::ProductURL::TypeInfo;
    return MTRReadAttribute<MTRCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeProductURLWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BasicInformation::Attributes::ProductURL::TypeInfo;
    MTRSubscribeAttribute<MTRCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeProductURLWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(CharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BasicInformation::Attributes::ProductURL::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeProductLabelWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BasicInformation::Attributes::ProductLabel::TypeInfo;
    return MTRReadAttribute<MTRCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeProductLabelWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BasicInformation::Attributes::ProductLabel::TypeInfo;
    MTRSubscribeAttribute<MTRCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeProductLabelWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(CharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BasicInformation::Attributes::ProductLabel::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSerialNumberWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BasicInformation::Attributes::SerialNumber::TypeInfo;
    return MTRReadAttribute<MTRCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeSerialNumberWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BasicInformation::Attributes::SerialNumber::TypeInfo;
    MTRSubscribeAttribute<MTRCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeSerialNumberWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(CharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BasicInformation::Attributes::SerialNumber::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeLocalConfigDisabledWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BasicInformation::Attributes::LocalConfigDisabled::TypeInfo;
    return MTRReadAttribute<MTRBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeLocalConfigDisabledWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeLocalConfigDisabledWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeLocalConfigDisabledWithValue:(NSNumber * _Nonnull)value
                                            params:(MTRWriteParams * _Nullable)params
                                        completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BasicInformation::Attributes::LocalConfigDisabled::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.boolValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeLocalConfigDisabledWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BasicInformation::Attributes::LocalConfigDisabled::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeLocalConfigDisabledWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BasicInformation::Attributes::LocalConfigDisabled::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeReachableWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BasicInformation::Attributes::Reachable::TypeInfo;
    return MTRReadAttribute<MTRBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeReachableWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BasicInformation::Attributes::Reachable::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeReachableWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BasicInformation::Attributes::Reachable::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeUniqueIDWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BasicInformation::Attributes::UniqueID::TypeInfo;
    return MTRReadAttribute<MTRCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeUniqueIDWithParams:(MTRSubscribeParams * _Nonnull)params
                     subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                               reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BasicInformation::Attributes::UniqueID::TypeInfo;
    MTRSubscribeAttribute<MTRCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeUniqueIDWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                        completion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(CharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BasicInformation::Attributes::UniqueID::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCapabilityMinimaWithCompletion:(void (^)(MTRBasicInformationClusterCapabilityMinimaStruct * _Nullable value,
                                                        NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BasicInformation::Attributes::CapabilityMinima::TypeInfo;
    return MTRReadAttribute<MTRBasicInformationCapabilityMinimaStructAttributeCallbackBridge,
        MTRBasicInformationClusterCapabilityMinimaStruct, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeCapabilityMinimaWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(MTRBasicInformationClusterCapabilityMinimaStruct * _Nullable value,
                                                         NSError * _Nullable error))reportHandler
{
    using TypeInfo = BasicInformation::Attributes::CapabilityMinima::TypeInfo;
    MTRSubscribeAttribute<MTRBasicInformationCapabilityMinimaStructAttributeCallbackSubscriptionBridge,
        MTRBasicInformationClusterCapabilityMinimaStruct, TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler,
        self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeCapabilityMinimaWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(MTRBasicInformationClusterCapabilityMinimaStruct * _Nullable value,
                                                        NSError * _Nullable error))completion
{
    auto * bridge = new MTRBasicInformationCapabilityMinimaStructAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(BasicInformationCapabilityMinimaStructAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BasicInformation::Attributes::CapabilityMinima::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeProductAppearanceWithCompletion:(void (^)(MTRBasicInformationClusterProductAppearanceStruct * _Nullable value,
                                                         NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BasicInformation::Attributes::ProductAppearance::TypeInfo;
    return MTRReadAttribute<MTRBasicInformationProductAppearanceStructAttributeCallbackBridge,
        MTRBasicInformationClusterProductAppearanceStruct, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeProductAppearanceWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(MTRBasicInformationClusterProductAppearanceStruct * _Nullable value,
                                                          NSError * _Nullable error))reportHandler
{
    using TypeInfo = BasicInformation::Attributes::ProductAppearance::TypeInfo;
    MTRSubscribeAttribute<MTRBasicInformationProductAppearanceStructAttributeCallbackSubscriptionBridge,
        MTRBasicInformationClusterProductAppearanceStruct, TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler,
        self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeProductAppearanceWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(MTRBasicInformationClusterProductAppearanceStruct * _Nullable value,
                                                         NSError * _Nullable error))completion
{
    auto * bridge = new MTRBasicInformationProductAppearanceStructAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(BasicInformationProductAppearanceStructAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BasicInformation::Attributes::ProductAppearance::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BasicInformation::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRBasicInformationGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BasicInformation::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRBasicInformationGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBasicInformationGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(BasicInformationGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BasicInformation::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BasicInformation::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRBasicInformationAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BasicInformation::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRBasicInformationAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBasicInformationAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(BasicInformationAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BasicInformation::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BasicInformation::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRBasicInformationEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BasicInformation::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRBasicInformationEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBasicInformationEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(BasicInformationEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BasicInformation::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BasicInformation::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRBasicInformationAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BasicInformation::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRBasicInformationAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBasicInformationAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(BasicInformationAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BasicInformation::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BasicInformation::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BasicInformation::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BasicInformation::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BasicInformation::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BasicInformation::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BasicInformation::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterBasic
@end

@implementation MTRBaseClusterBasic (Deprecated)

- (void)mfgSpecificPingWithParams:(MTRBasicClusterMfgSpecificPingParams * _Nullable)params
                completionHandler:(MTRStatusCompletion)completionHandler
{
    [self mfgSpecificPingWithParams:params completion:completionHandler];
}
- (void)mfgSpecificPingWithCompletionHandler:(MTRStatusCompletion)completionHandler
{
    [self mfgSpecificPingWithParams:nil completionHandler:completionHandler];
}

- (void)readAttributeDataModelRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeDataModelRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeDataModelRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeDataModelRevisionWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSNumber *>(value), error);
                                          }];
}
+ (void)readAttributeDataModelRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDataModelRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}

- (void)readAttributeVendorNameWithCompletionHandler:(void (^)(
                                                         NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeVendorNameWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)subscribeAttributeVendorNameWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeVendorNameWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSString *>(value), error);
                                   }];
}
+ (void)readAttributeVendorNameWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeVendorNameWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSString *>(value), error);
                                            }];
}

- (void)readAttributeVendorIDWithCompletionHandler:(void (^)(
                                                       NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeVendorIDWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeVendorIDWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeVendorIDWithParams:subscribeParams
                       subscriptionEstablished:subscriptionEstablishedHandler
                                 reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                     // Cast is safe because subclass does not add any selectors.
                                     reportHandler(static_cast<NSNumber *>(value), error);
                                 }];
}
+ (void)readAttributeVendorIDWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeVendorIDWithClusterStateCache:attributeCacheContainer.realContainer
                                            endpoint:endpoint
                                               queue:queue
                                          completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              completionHandler(static_cast<NSNumber *>(value), error);
                                          }];
}

- (void)readAttributeProductNameWithCompletionHandler:(void (^)(
                                                          NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeProductNameWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)subscribeAttributeProductNameWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeProductNameWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSString *>(value), error);
                                    }];
}
+ (void)readAttributeProductNameWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeProductNameWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSString *>(value), error);
                                             }];
}

- (void)readAttributeProductIDWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeProductIDWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeProductIDWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeProductIDWithParams:subscribeParams
                        subscriptionEstablished:subscriptionEstablishedHandler
                                  reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                      // Cast is safe because subclass does not add any selectors.
                                      reportHandler(static_cast<NSNumber *>(value), error);
                                  }];
}
+ (void)readAttributeProductIDWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeProductIDWithClusterStateCache:attributeCacheContainer.realContainer
                                             endpoint:endpoint
                                                queue:queue
                                           completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               completionHandler(static_cast<NSNumber *>(value), error);
                                           }];
}

- (void)readAttributeNodeLabelWithCompletionHandler:(void (^)(
                                                        NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNodeLabelWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)writeAttributeNodeLabelWithValue:(NSString * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNodeLabelWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeNodeLabelWithValue:(NSString * _Nonnull)value
                                  params:(MTRWriteParams * _Nullable)params
                       completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNodeLabelWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeNodeLabelWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNodeLabelWithParams:subscribeParams
                        subscriptionEstablished:subscriptionEstablishedHandler
                                  reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                      // Cast is safe because subclass does not add any selectors.
                                      reportHandler(static_cast<NSString *>(value), error);
                                  }];
}
+ (void)readAttributeNodeLabelWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNodeLabelWithClusterStateCache:attributeCacheContainer.realContainer
                                             endpoint:endpoint
                                                queue:queue
                                           completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               completionHandler(static_cast<NSString *>(value), error);
                                           }];
}

- (void)readAttributeLocationWithCompletionHandler:(void (^)(
                                                       NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLocationWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)writeAttributeLocationWithValue:(NSString * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeLocationWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeLocationWithValue:(NSString * _Nonnull)value
                                 params:(MTRWriteParams * _Nullable)params
                      completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeLocationWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeLocationWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeLocationWithParams:subscribeParams
                       subscriptionEstablished:subscriptionEstablishedHandler
                                 reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                     // Cast is safe because subclass does not add any selectors.
                                     reportHandler(static_cast<NSString *>(value), error);
                                 }];
}
+ (void)readAttributeLocationWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLocationWithClusterStateCache:attributeCacheContainer.realContainer
                                            endpoint:endpoint
                                               queue:queue
                                          completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              completionHandler(static_cast<NSString *>(value), error);
                                          }];
}

- (void)readAttributeHardwareVersionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeHardwareVersionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeHardwareVersionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeHardwareVersionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeHardwareVersionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeHardwareVersionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (void)readAttributeHardwareVersionStringWithCompletionHandler:(void (^)(NSString * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    [self readAttributeHardwareVersionStringWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)subscribeAttributeHardwareVersionStringWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeHardwareVersionStringWithParams:subscribeParams
                                    subscriptionEstablished:subscriptionEstablishedHandler
                                              reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  reportHandler(static_cast<NSString *>(value), error);
                                              }];
}
+ (void)readAttributeHardwareVersionStringWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeHardwareVersionStringWithClusterStateCache:attributeCacheContainer.realContainer
                                                         endpoint:endpoint
                                                            queue:queue
                                                       completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                                           // Cast is safe because subclass does not add any selectors.
                                                           completionHandler(static_cast<NSString *>(value), error);
                                                       }];
}

- (void)readAttributeSoftwareVersionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeSoftwareVersionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeSoftwareVersionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeSoftwareVersionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeSoftwareVersionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSoftwareVersionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (void)readAttributeSoftwareVersionStringWithCompletionHandler:(void (^)(NSString * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    [self readAttributeSoftwareVersionStringWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)subscribeAttributeSoftwareVersionStringWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeSoftwareVersionStringWithParams:subscribeParams
                                    subscriptionEstablished:subscriptionEstablishedHandler
                                              reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  reportHandler(static_cast<NSString *>(value), error);
                                              }];
}
+ (void)readAttributeSoftwareVersionStringWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSoftwareVersionStringWithClusterStateCache:attributeCacheContainer.realContainer
                                                         endpoint:endpoint
                                                            queue:queue
                                                       completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                                           // Cast is safe because subclass does not add any selectors.
                                                           completionHandler(static_cast<NSString *>(value), error);
                                                       }];
}

- (void)readAttributeManufacturingDateWithCompletionHandler:(void (^)(NSString * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeManufacturingDateWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)subscribeAttributeManufacturingDateWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeManufacturingDateWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSString *>(value), error);
                                          }];
}
+ (void)readAttributeManufacturingDateWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeManufacturingDateWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSString *>(value), error);
                                                   }];
}

- (void)readAttributePartNumberWithCompletionHandler:(void (^)(
                                                         NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePartNumberWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)subscribeAttributePartNumberWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePartNumberWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSString *>(value), error);
                                   }];
}
+ (void)readAttributePartNumberWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePartNumberWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSString *>(value), error);
                                            }];
}

- (void)readAttributeProductURLWithCompletionHandler:(void (^)(
                                                         NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeProductURLWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)subscribeAttributeProductURLWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeProductURLWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSString *>(value), error);
                                   }];
}
+ (void)readAttributeProductURLWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeProductURLWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSString *>(value), error);
                                            }];
}

- (void)readAttributeProductLabelWithCompletionHandler:(void (^)(
                                                           NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeProductLabelWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)subscribeAttributeProductLabelWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeProductLabelWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSString *>(value), error);
                                     }];
}
+ (void)readAttributeProductLabelWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeProductLabelWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSString *>(value), error);
                                              }];
}

- (void)readAttributeSerialNumberWithCompletionHandler:(void (^)(
                                                           NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSerialNumberWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)subscribeAttributeSerialNumberWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeSerialNumberWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSString *>(value), error);
                                     }];
}
+ (void)readAttributeSerialNumberWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSerialNumberWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSString *>(value), error);
                                              }];
}

- (void)readAttributeLocalConfigDisabledWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeLocalConfigDisabledWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeLocalConfigDisabledWithValue:(NSNumber * _Nonnull)value
                                 completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeLocalConfigDisabledWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeLocalConfigDisabledWithValue:(NSNumber * _Nonnull)value
                                            params:(MTRWriteParams * _Nullable)params
                                 completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeLocalConfigDisabledWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeLocalConfigDisabledWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeLocalConfigDisabledWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSNumber *>(value), error);
                                            }];
}
+ (void)readAttributeLocalConfigDisabledWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLocalConfigDisabledWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}

- (void)readAttributeReachableWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeReachableWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeReachableWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeReachableWithParams:subscribeParams
                        subscriptionEstablished:subscriptionEstablishedHandler
                                  reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                      // Cast is safe because subclass does not add any selectors.
                                      reportHandler(static_cast<NSNumber *>(value), error);
                                  }];
}
+ (void)readAttributeReachableWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeReachableWithClusterStateCache:attributeCacheContainer.realContainer
                                             endpoint:endpoint
                                                queue:queue
                                           completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               completionHandler(static_cast<NSNumber *>(value), error);
                                           }];
}

- (void)readAttributeUniqueIDWithCompletionHandler:(void (^)(
                                                       NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeUniqueIDWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)subscribeAttributeUniqueIDWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeUniqueIDWithParams:subscribeParams
                       subscriptionEstablished:subscriptionEstablishedHandler
                                 reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                     // Cast is safe because subclass does not add any selectors.
                                     reportHandler(static_cast<NSString *>(value), error);
                                 }];
}
+ (void)readAttributeUniqueIDWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeUniqueIDWithClusterStateCache:attributeCacheContainer.realContainer
                                            endpoint:endpoint
                                               queue:queue
                                          completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              completionHandler(static_cast<NSString *>(value), error);
                                          }];
}

- (void)readAttributeCapabilityMinimaWithCompletionHandler:(void (^)(MTRBasicClusterCapabilityMinimaStruct * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeCapabilityMinimaWithCompletion:^(
        MTRBasicInformationClusterCapabilityMinimaStruct * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<MTRBasicClusterCapabilityMinimaStruct *>(value), error);
    }];
}
- (void)subscribeAttributeCapabilityMinimaWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:
                                      (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:(void (^)(MTRBasicClusterCapabilityMinimaStruct * _Nullable value,
                                                              NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeCapabilityMinimaWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(MTRBasicInformationClusterCapabilityMinimaStruct * _Nullable value,
                                             NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<MTRBasicClusterCapabilityMinimaStruct *>(value), error);
                                         }];
}
+ (void)readAttributeCapabilityMinimaWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:(void (^)(MTRBasicClusterCapabilityMinimaStruct * _Nullable value,
                                                            NSError * _Nullable error))completionHandler
{
    [self readAttributeCapabilityMinimaWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(MTRBasicInformationClusterCapabilityMinimaStruct * _Nullable value,
                                                      NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(
                                                          static_cast<MTRBasicClusterCapabilityMinimaStruct *>(value), error);
                                                  }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterOTASoftwareUpdateProvider

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)queryImageWithParams:(MTROTASoftwareUpdateProviderClusterQueryImageParams *)params
                  completion:(void (^)(MTROTASoftwareUpdateProviderClusterQueryImageResponseParams * _Nullable data,
                                 NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTROTASoftwareUpdateProviderClusterQueryImageResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            OTASoftwareUpdateProviderClusterQueryImageResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTROTASoftwareUpdateProviderClusterQueryImageResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            OtaSoftwareUpdateProvider::Commands::QueryImage::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.vendorID = static_cast<std::remove_reference_t<decltype(request.vendorID)>>(params.vendorID.unsignedShortValue);
            request.productID = params.productID.unsignedShortValue;
            request.softwareVersion = params.softwareVersion.unsignedIntValue;
            {
                using ListType_0 = std::remove_reference_t<decltype(request.protocolsSupported)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (params.protocolsSupported.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(params.protocolsSupported.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < params.protocolsSupported.count; ++i_0) {
                        if (![params.protocolsSupported[i_0] isKindOfClass:[NSNumber class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (NSNumber *) params.protocolsSupported[i_0];
                        listHolder_0->mList[i_0]
                            = static_cast<std::remove_reference_t<decltype(listHolder_0->mList[i_0])>>(element_0.unsignedCharValue);
                    }
                    request.protocolsSupported = ListType_0(listHolder_0->mList, params.protocolsSupported.count);
                } else {
                    request.protocolsSupported = ListType_0();
                }
            }
            if (params.hardwareVersion != nil) {
                auto & definedValue_0 = request.hardwareVersion.Emplace();
                definedValue_0 = params.hardwareVersion.unsignedShortValue;
            }
            if (params.location != nil) {
                auto & definedValue_0 = request.location.Emplace();
                definedValue_0 = [self asCharSpan:params.location];
            }
            if (params.requestorCanConsent != nil) {
                auto & definedValue_0 = request.requestorCanConsent.Emplace();
                definedValue_0 = params.requestorCanConsent.boolValue;
            }
            if (params.metadataForProvider != nil) {
                auto & definedValue_0 = request.metadataForProvider.Emplace();
                definedValue_0 = [self asByteSpan:params.metadataForProvider];
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)applyUpdateRequestWithParams:(MTROTASoftwareUpdateProviderClusterApplyUpdateRequestParams *)params
                          completion:(void (^)(MTROTASoftwareUpdateProviderClusterApplyUpdateResponseParams * _Nullable data,
                                         NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTROTASoftwareUpdateProviderClusterApplyUpdateResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            OTASoftwareUpdateProviderClusterApplyUpdateResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTROTASoftwareUpdateProviderClusterApplyUpdateResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            OtaSoftwareUpdateProvider::Commands::ApplyUpdateRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.updateToken = [self asByteSpan:params.updateToken];
            request.newVersion = params.newVersion.unsignedIntValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)notifyUpdateAppliedWithParams:(MTROTASoftwareUpdateProviderClusterNotifyUpdateAppliedParams *)params
                           completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            OtaSoftwareUpdateProvider::Commands::NotifyUpdateApplied::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.updateToken = [self asByteSpan:params.updateToken];
            request.softwareVersion = params.softwareVersion.unsignedIntValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OtaSoftwareUpdateProvider::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTROTASoftwareUpdateProviderGeneratedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OtaSoftwareUpdateProvider::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTROTASoftwareUpdateProviderGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTROTASoftwareUpdateProviderGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(OTASoftwareUpdateProviderGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OtaSoftwareUpdateProvider::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OtaSoftwareUpdateProvider::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTROTASoftwareUpdateProviderAcceptedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OtaSoftwareUpdateProvider::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTROTASoftwareUpdateProviderAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTROTASoftwareUpdateProviderAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(OTASoftwareUpdateProviderAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OtaSoftwareUpdateProvider::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OtaSoftwareUpdateProvider::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTROTASoftwareUpdateProviderEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OtaSoftwareUpdateProvider::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTROTASoftwareUpdateProviderEventListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTROTASoftwareUpdateProviderEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(OTASoftwareUpdateProviderEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OtaSoftwareUpdateProvider::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OtaSoftwareUpdateProvider::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTROTASoftwareUpdateProviderAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OtaSoftwareUpdateProvider::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTROTASoftwareUpdateProviderAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTROTASoftwareUpdateProviderAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(OTASoftwareUpdateProviderAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OtaSoftwareUpdateProvider::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OtaSoftwareUpdateProvider::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OtaSoftwareUpdateProvider::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OtaSoftwareUpdateProvider::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OtaSoftwareUpdateProvider::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OtaSoftwareUpdateProvider::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OtaSoftwareUpdateProvider::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterOtaSoftwareUpdateProvider
@end

@implementation MTRBaseClusterOtaSoftwareUpdateProvider (Deprecated)

- (void)queryImageWithParams:(MTROtaSoftwareUpdateProviderClusterQueryImageParams *)params
           completionHandler:(void (^)(MTROtaSoftwareUpdateProviderClusterQueryImageResponseParams * _Nullable data,
                                 NSError * _Nullable error))completionHandler
{
    [self queryImageWithParams:params
                    completion:^(
                        MTROTASoftwareUpdateProviderClusterQueryImageResponseParams * _Nullable data, NSError * _Nullable error) {
                        // Cast is safe because subclass does not add any selectors.
                        completionHandler(static_cast<MTROtaSoftwareUpdateProviderClusterQueryImageResponseParams *>(data), error);
                    }];
}
- (void)applyUpdateRequestWithParams:(MTROtaSoftwareUpdateProviderClusterApplyUpdateRequestParams *)params
                   completionHandler:(void (^)(MTROtaSoftwareUpdateProviderClusterApplyUpdateResponseParams * _Nullable data,
                                         NSError * _Nullable error))completionHandler
{
    [self applyUpdateRequestWithParams:params
                            completion:^(MTROTASoftwareUpdateProviderClusterApplyUpdateResponseParams * _Nullable data,
                                NSError * _Nullable error) {
                                // Cast is safe because subclass does not add any selectors.
                                completionHandler(
                                    static_cast<MTROtaSoftwareUpdateProviderClusterApplyUpdateResponseParams *>(data), error);
                            }];
}
- (void)notifyUpdateAppliedWithParams:(MTROtaSoftwareUpdateProviderClusterNotifyUpdateAppliedParams *)params
                    completionHandler:(MTRStatusCompletion)completionHandler
{
    [self notifyUpdateAppliedWithParams:params completion:completionHandler];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterOTASoftwareUpdateRequestor

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)announceOTAProviderWithParams:(MTROTASoftwareUpdateRequestorClusterAnnounceOTAProviderParams *)params
                           completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            OtaSoftwareUpdateRequestor::Commands::AnnounceOTAProvider::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.providerNodeID = params.providerNodeID.unsignedLongLongValue;
            request.vendorID = static_cast<std::remove_reference_t<decltype(request.vendorID)>>(params.vendorID.unsignedShortValue);
            request.announcementReason = static_cast<std::remove_reference_t<decltype(request.announcementReason)>>(
                params.announcementReason.unsignedCharValue);
            if (params.metadataForNode != nil) {
                auto & definedValue_0 = request.metadataForNode.Emplace();
                definedValue_0 = [self asByteSpan:params.metadataForNode];
            }
            request.endpoint = params.endpoint.unsignedShortValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeDefaultOTAProvidersWithParams:(MTRReadParams * _Nullable)params
                                        completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{ // Make a copy of params before we go async.
    params = [params copy];
    using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::DefaultOTAProviders::TypeInfo;
    return MTRReadAttribute<MTROTASoftwareUpdateRequestorDefaultOTAProvidersListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeDefaultOTAProvidersWithValue:(NSArray * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeDefaultOTAProvidersWithValue:(NSArray * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeDefaultOTAProvidersWithValue:(NSArray * _Nonnull)value
                                            params:(MTRWriteParams * _Nullable)params
                                        completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::DefaultOTAProviders::TypeInfo;
            TypeInfo::Type cppValue;
            {
                using ListType_0 = std::remove_reference_t<decltype(cppValue)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (value.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(value.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < value.count; ++i_0) {
                        if (![value[i_0] isKindOfClass:[MTROTASoftwareUpdateRequestorClusterProviderLocation class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (MTROTASoftwareUpdateRequestorClusterProviderLocation *) value[i_0];
                        listHolder_0->mList[i_0].providerNodeID = element_0.providerNodeID.unsignedLongLongValue;
                        listHolder_0->mList[i_0].endpoint = element_0.endpoint.unsignedShortValue;
                        listHolder_0->mList[i_0].fabricIndex = element_0.fabricIndex.unsignedCharValue;
                    }
                    cppValue = ListType_0(listHolder_0->mList, value.count);
                } else {
                    cppValue = ListType_0();
                }
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeDefaultOTAProvidersWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::DefaultOTAProviders::TypeInfo;
    MTRSubscribeAttribute<MTROTASoftwareUpdateRequestorDefaultOTAProvidersListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeDefaultOTAProvidersWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTROTASoftwareUpdateRequestorDefaultOTAProvidersListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(OTASoftwareUpdateRequestorDefaultOTAProvidersListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::DefaultOTAProviders::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeUpdatePossibleWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::UpdatePossible::TypeInfo;
    return MTRReadAttribute<MTRBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeUpdatePossibleWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::UpdatePossible::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeUpdatePossibleWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::UpdatePossible::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeUpdateStateWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::UpdateState::TypeInfo;
    return MTRReadAttribute<MTROTASoftwareUpdateRequestorClusterOTAUpdateStateEnumAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeUpdateStateWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::UpdateState::TypeInfo;
    MTRSubscribeAttribute<MTROTASoftwareUpdateRequestorClusterOTAUpdateStateEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeUpdateStateWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTROTASoftwareUpdateRequestorClusterOTAUpdateStateEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(OTASoftwareUpdateRequestorClusterOTAUpdateStateEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::UpdateState::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeUpdateStateProgressWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::UpdateStateProgress::TypeInfo;
    return MTRReadAttribute<MTRNullableInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeUpdateStateProgressWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::UpdateStateProgress::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeUpdateStateProgressWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::UpdateStateProgress::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTROTASoftwareUpdateRequestorGeneratedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTROTASoftwareUpdateRequestorGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTROTASoftwareUpdateRequestorGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(OTASoftwareUpdateRequestorGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTROTASoftwareUpdateRequestorAcceptedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTROTASoftwareUpdateRequestorAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTROTASoftwareUpdateRequestorAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(OTASoftwareUpdateRequestorAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTROTASoftwareUpdateRequestorEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTROTASoftwareUpdateRequestorEventListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTROTASoftwareUpdateRequestorEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(OTASoftwareUpdateRequestorEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTROTASoftwareUpdateRequestorAttributeListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTROTASoftwareUpdateRequestorAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTROTASoftwareUpdateRequestorAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(OTASoftwareUpdateRequestorAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterOtaSoftwareUpdateRequestor
@end

@implementation MTRBaseClusterOtaSoftwareUpdateRequestor (Deprecated)

- (void)announceOtaProviderWithParams:(MTROtaSoftwareUpdateRequestorClusterAnnounceOtaProviderParams *)params
                    completionHandler:(MTRStatusCompletion)completionHandler
{
    [self announceOTAProviderWithParams:params completion:completionHandler];
}

- (void)readAttributeDefaultOtaProvidersWithParams:(MTRReadParams * _Nullable)params
                                 completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDefaultOTAProvidersWithParams:params
                                          completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              completionHandler(static_cast<NSArray *>(value), error);
                                          }];
}
- (void)writeAttributeDefaultOtaProvidersWithValue:(NSArray * _Nonnull)value
                                 completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeDefaultOTAProvidersWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeDefaultOtaProvidersWithValue:(NSArray * _Nonnull)value
                                            params:(MTRWriteParams * _Nullable)params
                                 completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeDefaultOTAProvidersWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeDefaultOtaProvidersWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeDefaultOTAProvidersWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeDefaultOtaProvidersWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDefaultOTAProvidersWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeUpdatePossibleWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeUpdatePossibleWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeUpdatePossibleWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeUpdatePossibleWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSNumber *>(value), error);
                                       }];
}
+ (void)readAttributeUpdatePossibleWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeUpdatePossibleWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSNumber *>(value), error);
                                                }];
}

- (void)readAttributeUpdateStateWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeUpdateStateWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeUpdateStateWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeUpdateStateWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSNumber *>(value), error);
                                    }];
}
+ (void)readAttributeUpdateStateWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeUpdateStateWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                             }];
}

- (void)readAttributeUpdateStateProgressWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeUpdateStateProgressWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeUpdateStateProgressWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeUpdateStateProgressWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSNumber *>(value), error);
                                            }];
}
+ (void)readAttributeUpdateStateProgressWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeUpdateStateProgressWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterLocalizationConfiguration

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)readAttributeActiveLocaleWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = LocalizationConfiguration::Attributes::ActiveLocale::TypeInfo;
    return MTRReadAttribute<MTRCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeActiveLocaleWithValue:(NSString * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeActiveLocaleWithValue:(NSString * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeActiveLocaleWithValue:(NSString * _Nonnull)value
                                     params:(MTRWriteParams * _Nullable)params
                                 completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = LocalizationConfiguration::Attributes::ActiveLocale::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = [self asCharSpan:value];

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeActiveLocaleWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = LocalizationConfiguration::Attributes::ActiveLocale::TypeInfo;
    MTRSubscribeAttribute<MTRCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeActiveLocaleWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(CharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LocalizationConfiguration::Attributes::ActiveLocale::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSupportedLocalesWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = LocalizationConfiguration::Attributes::SupportedLocales::TypeInfo;
    return MTRReadAttribute<MTRLocalizationConfigurationSupportedLocalesListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeSupportedLocalesWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = LocalizationConfiguration::Attributes::SupportedLocales::TypeInfo;
    MTRSubscribeAttribute<MTRLocalizationConfigurationSupportedLocalesListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeSupportedLocalesWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRLocalizationConfigurationSupportedLocalesListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(LocalizationConfigurationSupportedLocalesListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LocalizationConfiguration::Attributes::SupportedLocales::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = LocalizationConfiguration::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRLocalizationConfigurationGeneratedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = LocalizationConfiguration::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRLocalizationConfigurationGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRLocalizationConfigurationGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(LocalizationConfigurationGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LocalizationConfiguration::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = LocalizationConfiguration::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRLocalizationConfigurationAcceptedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = LocalizationConfiguration::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRLocalizationConfigurationAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRLocalizationConfigurationAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(LocalizationConfigurationAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LocalizationConfiguration::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = LocalizationConfiguration::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRLocalizationConfigurationEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = LocalizationConfiguration::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRLocalizationConfigurationEventListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRLocalizationConfigurationEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(LocalizationConfigurationEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LocalizationConfiguration::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = LocalizationConfiguration::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRLocalizationConfigurationAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = LocalizationConfiguration::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRLocalizationConfigurationAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRLocalizationConfigurationAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(LocalizationConfigurationAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LocalizationConfiguration::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = LocalizationConfiguration::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = LocalizationConfiguration::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LocalizationConfiguration::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = LocalizationConfiguration::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = LocalizationConfiguration::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LocalizationConfiguration::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterLocalizationConfiguration (Deprecated)

- (void)readAttributeActiveLocaleWithCompletionHandler:(void (^)(
                                                           NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeActiveLocaleWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)writeAttributeActiveLocaleWithValue:(NSString * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeActiveLocaleWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeActiveLocaleWithValue:(NSString * _Nonnull)value
                                     params:(MTRWriteParams * _Nullable)params
                          completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeActiveLocaleWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeActiveLocaleWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeActiveLocaleWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSString *>(value), error);
                                     }];
}
+ (void)readAttributeActiveLocaleWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeActiveLocaleWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSString *>(value), error);
                                              }];
}

- (void)readAttributeSupportedLocalesWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeSupportedLocalesWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)
    subscribeAttributeSupportedLocalesWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeSupportedLocalesWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSArray *>(value), error);
                                         }];
}
+ (void)readAttributeSupportedLocalesWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSupportedLocalesWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSArray *>(value), error);
                                                  }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterTimeFormatLocalization

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)readAttributeHourFormatWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TimeFormatLocalization::Attributes::HourFormat::TypeInfo;
    return MTRReadAttribute<MTRTimeFormatLocalizationClusterHourFormatEnumAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeHourFormatWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeHourFormatWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeHourFormatWithValue:(NSNumber * _Nonnull)value
                                   params:(MTRWriteParams * _Nullable)params
                               completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TimeFormatLocalization::Attributes::HourFormat::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = static_cast<std::remove_reference_t<decltype(cppValue)>>(value.unsignedCharValue);

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeHourFormatWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TimeFormatLocalization::Attributes::HourFormat::TypeInfo;
    MTRSubscribeAttribute<MTRTimeFormatLocalizationClusterHourFormatEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeHourFormatWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRTimeFormatLocalizationClusterHourFormatEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(TimeFormatLocalizationClusterHourFormatEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TimeFormatLocalization::Attributes::HourFormat::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeActiveCalendarTypeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TimeFormatLocalization::Attributes::ActiveCalendarType::TypeInfo;
    return MTRReadAttribute<MTRTimeFormatLocalizationClusterCalendarTypeEnumAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeActiveCalendarTypeWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeActiveCalendarTypeWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeActiveCalendarTypeWithValue:(NSNumber * _Nonnull)value
                                           params:(MTRWriteParams * _Nullable)params
                                       completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TimeFormatLocalization::Attributes::ActiveCalendarType::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = static_cast<std::remove_reference_t<decltype(cppValue)>>(value.unsignedCharValue);

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeActiveCalendarTypeWithParams:(MTRSubscribeParams * _Nonnull)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TimeFormatLocalization::Attributes::ActiveCalendarType::TypeInfo;
    MTRSubscribeAttribute<MTRTimeFormatLocalizationClusterCalendarTypeEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeActiveCalendarTypeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                                  completion:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRTimeFormatLocalizationClusterCalendarTypeEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(TimeFormatLocalizationClusterCalendarTypeEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TimeFormatLocalization::Attributes::ActiveCalendarType::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSupportedCalendarTypesWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TimeFormatLocalization::Attributes::SupportedCalendarTypes::TypeInfo;
    return MTRReadAttribute<MTRTimeFormatLocalizationSupportedCalendarTypesListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeSupportedCalendarTypesWithParams:(MTRSubscribeParams * _Nonnull)params
                                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                             reportHandler:
                                                 (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TimeFormatLocalization::Attributes::SupportedCalendarTypes::TypeInfo;
    MTRSubscribeAttribute<MTRTimeFormatLocalizationSupportedCalendarTypesListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeSupportedCalendarTypesWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                                      completion:
                                                          (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRTimeFormatLocalizationSupportedCalendarTypesListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(TimeFormatLocalizationSupportedCalendarTypesListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TimeFormatLocalization::Attributes::SupportedCalendarTypes::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TimeFormatLocalization::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRTimeFormatLocalizationGeneratedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TimeFormatLocalization::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRTimeFormatLocalizationGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRTimeFormatLocalizationGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(TimeFormatLocalizationGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TimeFormatLocalization::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TimeFormatLocalization::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRTimeFormatLocalizationAcceptedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TimeFormatLocalization::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRTimeFormatLocalizationAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRTimeFormatLocalizationAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(TimeFormatLocalizationAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TimeFormatLocalization::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TimeFormatLocalization::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRTimeFormatLocalizationEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TimeFormatLocalization::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRTimeFormatLocalizationEventListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRTimeFormatLocalizationEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(TimeFormatLocalizationEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TimeFormatLocalization::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TimeFormatLocalization::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRTimeFormatLocalizationAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TimeFormatLocalization::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRTimeFormatLocalizationAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRTimeFormatLocalizationAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(TimeFormatLocalizationAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TimeFormatLocalization::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TimeFormatLocalization::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TimeFormatLocalization::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TimeFormatLocalization::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TimeFormatLocalization::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TimeFormatLocalization::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TimeFormatLocalization::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterTimeFormatLocalization (Deprecated)

- (void)readAttributeHourFormatWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeHourFormatWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeHourFormatWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeHourFormatWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeHourFormatWithValue:(NSNumber * _Nonnull)value
                                   params:(MTRWriteParams * _Nullable)params
                        completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeHourFormatWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeHourFormatWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeHourFormatWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeHourFormatWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeHourFormatWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeActiveCalendarTypeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    [self readAttributeActiveCalendarTypeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeActiveCalendarTypeWithValue:(NSNumber * _Nonnull)value
                                completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeActiveCalendarTypeWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeActiveCalendarTypeWithValue:(NSNumber * _Nonnull)value
                                           params:(MTRWriteParams * _Nullable)params
                                completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeActiveCalendarTypeWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeActiveCalendarTypeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:
                                        (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeActiveCalendarTypeWithParams:subscribeParams
                                 subscriptionEstablished:subscriptionEstablishedHandler
                                           reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               reportHandler(static_cast<NSNumber *>(value), error);
                                           }];
}
+ (void)readAttributeActiveCalendarTypeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeActiveCalendarTypeWithClusterStateCache:attributeCacheContainer.realContainer
                                                      endpoint:endpoint
                                                         queue:queue
                                                    completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                        // Cast is safe because subclass does not add any selectors.
                                                        completionHandler(static_cast<NSNumber *>(value), error);
                                                    }];
}

- (void)readAttributeSupportedCalendarTypesWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    [self readAttributeSupportedCalendarTypesWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeSupportedCalendarTypesWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                                         params:(MTRSubscribeParams * _Nullable)params
                                        subscriptionEstablished:
                                            (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                  reportHandler:
                                                      (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeSupportedCalendarTypesWithParams:subscribeParams
                                     subscriptionEstablished:subscriptionEstablishedHandler
                                               reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   reportHandler(static_cast<NSArray *>(value), error);
                                               }];
}
+ (void)readAttributeSupportedCalendarTypesWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                            completionHandler:
                                                (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSupportedCalendarTypesWithClusterStateCache:attributeCacheContainer.realContainer
                                                          endpoint:endpoint
                                                             queue:queue
                                                        completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                            // Cast is safe because subclass does not add any selectors.
                                                            completionHandler(static_cast<NSArray *>(value), error);
                                                        }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterUnitLocalization

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)readAttributeTemperatureUnitWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitLocalization::Attributes::TemperatureUnit::TypeInfo;
    return MTRReadAttribute<MTRUnitLocalizationClusterTempUnitEnumAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeTemperatureUnitWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeTemperatureUnitWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeTemperatureUnitWithValue:(NSNumber * _Nonnull)value
                                        params:(MTRWriteParams * _Nullable)params
                                    completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitLocalization::Attributes::TemperatureUnit::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = static_cast<std::remove_reference_t<decltype(cppValue)>>(value.unsignedCharValue);

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeTemperatureUnitWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitLocalization::Attributes::TemperatureUnit::TypeInfo;
    MTRSubscribeAttribute<MTRUnitLocalizationClusterTempUnitEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeTemperatureUnitWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRUnitLocalizationClusterTempUnitEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(UnitLocalizationClusterTempUnitEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitLocalization::Attributes::TemperatureUnit::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitLocalization::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRUnitLocalizationGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitLocalization::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRUnitLocalizationGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRUnitLocalizationGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(UnitLocalizationGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitLocalization::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitLocalization::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRUnitLocalizationAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitLocalization::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRUnitLocalizationAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRUnitLocalizationAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(UnitLocalizationAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitLocalization::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitLocalization::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRUnitLocalizationEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitLocalization::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRUnitLocalizationEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRUnitLocalizationEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(UnitLocalizationEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitLocalization::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitLocalization::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRUnitLocalizationAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitLocalization::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRUnitLocalizationAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRUnitLocalizationAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(UnitLocalizationAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitLocalization::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitLocalization::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitLocalization::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitLocalization::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitLocalization::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitLocalization::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitLocalization::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterUnitLocalization (Deprecated)

- (void)readAttributeTemperatureUnitWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeTemperatureUnitWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeTemperatureUnitWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeTemperatureUnitWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeTemperatureUnitWithValue:(NSNumber * _Nonnull)value
                                        params:(MTRWriteParams * _Nullable)params
                             completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeTemperatureUnitWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeTemperatureUnitWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeTemperatureUnitWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeTemperatureUnitWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeTemperatureUnitWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterPowerSourceConfiguration

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)readAttributeSourcesWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSourceConfiguration::Attributes::Sources::TypeInfo;
    return MTRReadAttribute<MTRPowerSourceConfigurationSourcesListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeSourcesWithParams:(MTRSubscribeParams * _Nonnull)params
                    subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                              reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSourceConfiguration::Attributes::Sources::TypeInfo;
    MTRSubscribeAttribute<MTRPowerSourceConfigurationSourcesListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeSourcesWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                       completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRPowerSourceConfigurationSourcesListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(PowerSourceConfigurationSourcesListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSourceConfiguration::Attributes::Sources::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSourceConfiguration::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRPowerSourceConfigurationGeneratedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSourceConfiguration::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRPowerSourceConfigurationGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRPowerSourceConfigurationGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(PowerSourceConfigurationGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSourceConfiguration::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSourceConfiguration::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRPowerSourceConfigurationAcceptedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSourceConfiguration::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRPowerSourceConfigurationAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRPowerSourceConfigurationAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(PowerSourceConfigurationAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSourceConfiguration::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSourceConfiguration::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRPowerSourceConfigurationEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSourceConfiguration::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRPowerSourceConfigurationEventListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRPowerSourceConfigurationEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(PowerSourceConfigurationEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSourceConfiguration::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSourceConfiguration::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRPowerSourceConfigurationAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSourceConfiguration::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRPowerSourceConfigurationAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRPowerSourceConfigurationAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(PowerSourceConfigurationAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSourceConfiguration::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSourceConfiguration::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSourceConfiguration::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSourceConfiguration::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSourceConfiguration::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSourceConfiguration::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSourceConfiguration::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterPowerSourceConfiguration (Deprecated)

- (void)readAttributeSourcesWithCompletionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSourcesWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeSourcesWithMinInterval:(NSNumber * _Nonnull)minInterval
                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                          params:(MTRSubscribeParams * _Nullable)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                   reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeSourcesWithParams:subscribeParams
                      subscriptionEstablished:subscriptionEstablishedHandler
                                reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                    // Cast is safe because subclass does not add any selectors.
                                    reportHandler(static_cast<NSArray *>(value), error);
                                }];
}
+ (void)readAttributeSourcesWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                      endpoint:(NSNumber *)endpoint
                                         queue:(dispatch_queue_t)queue
                             completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSourcesWithClusterStateCache:attributeCacheContainer.realContainer
                                           endpoint:endpoint
                                              queue:queue
                                         completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             completionHandler(static_cast<NSArray *>(value), error);
                                         }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterPowerSource

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)readAttributeStatusWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSource::Attributes::Status::TypeInfo;
    return MTRReadAttribute<MTRPowerSourceClusterPowerSourceStatusEnumAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeStatusWithParams:(MTRSubscribeParams * _Nonnull)params
                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                             reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSource::Attributes::Status::TypeInfo;
    MTRSubscribeAttribute<MTRPowerSourceClusterPowerSourceStatusEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeStatusWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                                      completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRPowerSourceClusterPowerSourceStatusEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(PowerSourceClusterPowerSourceStatusEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::Status::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeOrderWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSource::Attributes::Order::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeOrderWithParams:(MTRSubscribeParams * _Nonnull)params
                  subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                            reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSource::Attributes::Order::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeOrderWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                                     completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::Order::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeDescriptionWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSource::Attributes::Description::TypeInfo;
    return MTRReadAttribute<MTRCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeDescriptionWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSource::Attributes::Description::TypeInfo;
    MTRSubscribeAttribute<MTRCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeDescriptionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(CharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::Description::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeWiredAssessedInputVoltageWithCompletion:(void (^)(
                                                                 NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSource::Attributes::WiredAssessedInputVoltage::TypeInfo;
    return MTRReadAttribute<MTRNullableInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeWiredAssessedInputVoltageWithParams:(MTRSubscribeParams * _Nonnull)params
                                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSource::Attributes::WiredAssessedInputVoltage::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeWiredAssessedInputVoltageWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                           endpoint:(NSNumber *)endpoint
                                                              queue:(dispatch_queue_t)queue
                                                         completion:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::WiredAssessedInputVoltage::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeWiredAssessedInputFrequencyWithCompletion:(void (^)(
                                                                   NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSource::Attributes::WiredAssessedInputFrequency::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeWiredAssessedInputFrequencyWithParams:(MTRSubscribeParams * _Nonnull)params
                                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSource::Attributes::WiredAssessedInputFrequency::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeWiredAssessedInputFrequencyWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                             endpoint:(NSNumber *)endpoint
                                                                queue:(dispatch_queue_t)queue
                                                           completion:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::WiredAssessedInputFrequency::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeWiredCurrentTypeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSource::Attributes::WiredCurrentType::TypeInfo;
    return MTRReadAttribute<MTRPowerSourceClusterWiredCurrentTypeEnumAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeWiredCurrentTypeWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSource::Attributes::WiredCurrentType::TypeInfo;
    MTRSubscribeAttribute<MTRPowerSourceClusterWiredCurrentTypeEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeWiredCurrentTypeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRPowerSourceClusterWiredCurrentTypeEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(PowerSourceClusterWiredCurrentTypeEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::WiredCurrentType::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeWiredAssessedCurrentWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSource::Attributes::WiredAssessedCurrent::TypeInfo;
    return MTRReadAttribute<MTRNullableInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeWiredAssessedCurrentWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSource::Attributes::WiredAssessedCurrent::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeWiredAssessedCurrentWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::WiredAssessedCurrent::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeWiredNominalVoltageWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSource::Attributes::WiredNominalVoltage::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeWiredNominalVoltageWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSource::Attributes::WiredNominalVoltage::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeWiredNominalVoltageWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::WiredNominalVoltage::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeWiredMaximumCurrentWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSource::Attributes::WiredMaximumCurrent::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeWiredMaximumCurrentWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSource::Attributes::WiredMaximumCurrent::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeWiredMaximumCurrentWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::WiredMaximumCurrent::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeWiredPresentWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSource::Attributes::WiredPresent::TypeInfo;
    return MTRReadAttribute<MTRBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeWiredPresentWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSource::Attributes::WiredPresent::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeWiredPresentWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::WiredPresent::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeActiveWiredFaultsWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSource::Attributes::ActiveWiredFaults::TypeInfo;
    return MTRReadAttribute<MTRPowerSourceActiveWiredFaultsListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeActiveWiredFaultsWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSource::Attributes::ActiveWiredFaults::TypeInfo;
    MTRSubscribeAttribute<MTRPowerSourceActiveWiredFaultsListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeActiveWiredFaultsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRPowerSourceActiveWiredFaultsListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(PowerSourceActiveWiredFaultsListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::ActiveWiredFaults::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBatVoltageWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSource::Attributes::BatVoltage::TypeInfo;
    return MTRReadAttribute<MTRNullableInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeBatVoltageWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSource::Attributes::BatVoltage::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeBatVoltageWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::BatVoltage::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBatPercentRemainingWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSource::Attributes::BatPercentRemaining::TypeInfo;
    return MTRReadAttribute<MTRNullableInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeBatPercentRemainingWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSource::Attributes::BatPercentRemaining::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeBatPercentRemainingWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::BatPercentRemaining::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBatTimeRemainingWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSource::Attributes::BatTimeRemaining::TypeInfo;
    return MTRReadAttribute<MTRNullableInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeBatTimeRemainingWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSource::Attributes::BatTimeRemaining::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeBatTimeRemainingWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::BatTimeRemaining::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBatChargeLevelWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSource::Attributes::BatChargeLevel::TypeInfo;
    return MTRReadAttribute<MTRPowerSourceClusterBatChargeLevelEnumAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeBatChargeLevelWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSource::Attributes::BatChargeLevel::TypeInfo;
    MTRSubscribeAttribute<MTRPowerSourceClusterBatChargeLevelEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeBatChargeLevelWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRPowerSourceClusterBatChargeLevelEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(PowerSourceClusterBatChargeLevelEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::BatChargeLevel::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBatReplacementNeededWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSource::Attributes::BatReplacementNeeded::TypeInfo;
    return MTRReadAttribute<MTRBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeBatReplacementNeededWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSource::Attributes::BatReplacementNeeded::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeBatReplacementNeededWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::BatReplacementNeeded::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBatReplaceabilityWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSource::Attributes::BatReplaceability::TypeInfo;
    return MTRReadAttribute<MTRPowerSourceClusterBatReplaceabilityEnumAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeBatReplaceabilityWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSource::Attributes::BatReplaceability::TypeInfo;
    MTRSubscribeAttribute<MTRPowerSourceClusterBatReplaceabilityEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeBatReplaceabilityWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRPowerSourceClusterBatReplaceabilityEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(PowerSourceClusterBatReplaceabilityEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::BatReplaceability::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBatPresentWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSource::Attributes::BatPresent::TypeInfo;
    return MTRReadAttribute<MTRBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeBatPresentWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSource::Attributes::BatPresent::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeBatPresentWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::BatPresent::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeActiveBatFaultsWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSource::Attributes::ActiveBatFaults::TypeInfo;
    return MTRReadAttribute<MTRPowerSourceActiveBatFaultsListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeActiveBatFaultsWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSource::Attributes::ActiveBatFaults::TypeInfo;
    MTRSubscribeAttribute<MTRPowerSourceActiveBatFaultsListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeActiveBatFaultsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRPowerSourceActiveBatFaultsListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(PowerSourceActiveBatFaultsListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::ActiveBatFaults::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBatReplacementDescriptionWithCompletion:(void (^)(
                                                                 NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSource::Attributes::BatReplacementDescription::TypeInfo;
    return MTRReadAttribute<MTRCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeBatReplacementDescriptionWithParams:(MTRSubscribeParams * _Nonnull)params
                                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                reportHandler:
                                                    (void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSource::Attributes::BatReplacementDescription::TypeInfo;
    MTRSubscribeAttribute<MTRCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeBatReplacementDescriptionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                           endpoint:(NSNumber *)endpoint
                                                              queue:(dispatch_queue_t)queue
                                                         completion:(void (^)(NSString * _Nullable value,
                                                                        NSError * _Nullable error))completion
{
    auto * bridge = new MTRCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(CharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::BatReplacementDescription::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBatCommonDesignationWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSource::Attributes::BatCommonDesignation::TypeInfo;
    return MTRReadAttribute<MTRPowerSourceClusterBatCommonDesignationEnumAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeBatCommonDesignationWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSource::Attributes::BatCommonDesignation::TypeInfo;
    MTRSubscribeAttribute<MTRPowerSourceClusterBatCommonDesignationEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeBatCommonDesignationWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRPowerSourceClusterBatCommonDesignationEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(PowerSourceClusterBatCommonDesignationEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::BatCommonDesignation::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBatANSIDesignationWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSource::Attributes::BatANSIDesignation::TypeInfo;
    return MTRReadAttribute<MTRCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeBatANSIDesignationWithParams:(MTRSubscribeParams * _Nonnull)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                         reportHandler:
                                             (void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSource::Attributes::BatANSIDesignation::TypeInfo;
    MTRSubscribeAttribute<MTRCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeBatANSIDesignationWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                                  completion:
                                                      (void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(CharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::BatANSIDesignation::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBatIECDesignationWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSource::Attributes::BatIECDesignation::TypeInfo;
    return MTRReadAttribute<MTRCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeBatIECDesignationWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSource::Attributes::BatIECDesignation::TypeInfo;
    MTRSubscribeAttribute<MTRCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeBatIECDesignationWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(CharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::BatIECDesignation::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBatApprovedChemistryWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSource::Attributes::BatApprovedChemistry::TypeInfo;
    return MTRReadAttribute<MTRPowerSourceClusterBatApprovedChemistryEnumAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeBatApprovedChemistryWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSource::Attributes::BatApprovedChemistry::TypeInfo;
    MTRSubscribeAttribute<MTRPowerSourceClusterBatApprovedChemistryEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeBatApprovedChemistryWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRPowerSourceClusterBatApprovedChemistryEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(PowerSourceClusterBatApprovedChemistryEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::BatApprovedChemistry::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBatCapacityWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSource::Attributes::BatCapacity::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeBatCapacityWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSource::Attributes::BatCapacity::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeBatCapacityWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::BatCapacity::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBatQuantityWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSource::Attributes::BatQuantity::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeBatQuantityWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSource::Attributes::BatQuantity::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeBatQuantityWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::BatQuantity::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBatChargeStateWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSource::Attributes::BatChargeState::TypeInfo;
    return MTRReadAttribute<MTRPowerSourceClusterBatChargeStateEnumAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeBatChargeStateWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSource::Attributes::BatChargeState::TypeInfo;
    MTRSubscribeAttribute<MTRPowerSourceClusterBatChargeStateEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeBatChargeStateWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRPowerSourceClusterBatChargeStateEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(PowerSourceClusterBatChargeStateEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::BatChargeState::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBatTimeToFullChargeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSource::Attributes::BatTimeToFullCharge::TypeInfo;
    return MTRReadAttribute<MTRNullableInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeBatTimeToFullChargeWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSource::Attributes::BatTimeToFullCharge::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeBatTimeToFullChargeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::BatTimeToFullCharge::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBatFunctionalWhileChargingWithCompletion:(void (^)(
                                                                  NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSource::Attributes::BatFunctionalWhileCharging::TypeInfo;
    return MTRReadAttribute<MTRBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeBatFunctionalWhileChargingWithParams:(MTRSubscribeParams * _Nonnull)params
                                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSource::Attributes::BatFunctionalWhileCharging::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeBatFunctionalWhileChargingWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                            endpoint:(NSNumber *)endpoint
                                                               queue:(dispatch_queue_t)queue
                                                          completion:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::BatFunctionalWhileCharging::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBatChargingCurrentWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSource::Attributes::BatChargingCurrent::TypeInfo;
    return MTRReadAttribute<MTRNullableInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeBatChargingCurrentWithParams:(MTRSubscribeParams * _Nonnull)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSource::Attributes::BatChargingCurrent::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeBatChargingCurrentWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                                  completion:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::BatChargingCurrent::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeActiveBatChargeFaultsWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSource::Attributes::ActiveBatChargeFaults::TypeInfo;
    return MTRReadAttribute<MTRPowerSourceActiveBatChargeFaultsListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeActiveBatChargeFaultsWithParams:(MTRSubscribeParams * _Nonnull)params
                                  subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                            reportHandler:
                                                (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSource::Attributes::ActiveBatChargeFaults::TypeInfo;
    MTRSubscribeAttribute<MTRPowerSourceActiveBatChargeFaultsListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeActiveBatChargeFaultsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                                     completion:
                                                         (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRPowerSourceActiveBatChargeFaultsListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(PowerSourceActiveBatChargeFaultsListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::ActiveBatChargeFaults::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSource::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRPowerSourceGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSource::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRPowerSourceGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRPowerSourceGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(PowerSourceGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSource::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRPowerSourceAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSource::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRPowerSourceAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRPowerSourceAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(PowerSourceAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSource::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRPowerSourceEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSource::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRPowerSourceEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRPowerSourceEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(PowerSourceEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSource::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRPowerSourceAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSource::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRPowerSourceAttributeListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRPowerSourceAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(PowerSourceAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSource::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSource::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PowerSource::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PowerSource::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterPowerSource (Deprecated)

- (void)readAttributeStatusWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeStatusWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeStatusWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeStatusWithParams:subscribeParams
                     subscriptionEstablished:subscriptionEstablishedHandler
                               reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                   // Cast is safe because subclass does not add any selectors.
                                   reportHandler(static_cast<NSNumber *>(value), error);
                               }];
}
+ (void)readAttributeStatusWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeStatusWithClusterStateCache:attributeCacheContainer.realContainer
                                          endpoint:endpoint
                                             queue:queue
                                        completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            completionHandler(static_cast<NSNumber *>(value), error);
                                        }];
}

- (void)readAttributeOrderWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOrderWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeOrderWithMinInterval:(NSNumber * _Nonnull)minInterval
                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                        params:(MTRSubscribeParams * _Nullable)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeOrderWithParams:subscribeParams
                    subscriptionEstablished:subscriptionEstablishedHandler
                              reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                  // Cast is safe because subclass does not add any selectors.
                                  reportHandler(static_cast<NSNumber *>(value), error);
                              }];
}
+ (void)readAttributeOrderWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                    endpoint:(NSNumber *)endpoint
                                       queue:(dispatch_queue_t)queue
                           completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOrderWithClusterStateCache:attributeCacheContainer.realContainer
                                         endpoint:endpoint
                                            queue:queue
                                       completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           completionHandler(static_cast<NSNumber *>(value), error);
                                       }];
}

- (void)readAttributeDescriptionWithCompletionHandler:(void (^)(
                                                          NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDescriptionWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)subscribeAttributeDescriptionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeDescriptionWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSString *>(value), error);
                                    }];
}
+ (void)readAttributeDescriptionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDescriptionWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSString *>(value), error);
                                             }];
}

- (void)readAttributeWiredAssessedInputVoltageWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    [self readAttributeWiredAssessedInputVoltageWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeWiredAssessedInputVoltageWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                                            params:(MTRSubscribeParams * _Nullable)params
                                           subscriptionEstablished:
                                               (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                     reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeWiredAssessedInputVoltageWithParams:subscribeParams
                                        subscriptionEstablished:subscriptionEstablishedHandler
                                                  reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      reportHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}
+ (void)readAttributeWiredAssessedInputVoltageWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                               completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    [self readAttributeWiredAssessedInputVoltageWithClusterStateCache:attributeCacheContainer.realContainer
                                                             endpoint:endpoint
                                                                queue:queue
                                                           completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                               // Cast is safe because subclass does not add any selectors.
                                                               completionHandler(static_cast<NSNumber *>(value), error);
                                                           }];
}

- (void)readAttributeWiredAssessedInputFrequencyWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))completionHandler
{
    [self readAttributeWiredAssessedInputFrequencyWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeWiredAssessedInputFrequencyWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                                              params:(MTRSubscribeParams * _Nullable)params
                                             subscriptionEstablished:
                                                 (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                       reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeWiredAssessedInputFrequencyWithParams:subscribeParams
                                          subscriptionEstablished:subscriptionEstablishedHandler
                                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                        // Cast is safe because subclass does not add any selectors.
                                                        reportHandler(static_cast<NSNumber *>(value), error);
                                                    }];
}
+ (void)readAttributeWiredAssessedInputFrequencyWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                          endpoint:(NSNumber *)endpoint
                                                             queue:(dispatch_queue_t)queue
                                                 completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completionHandler
{
    [self readAttributeWiredAssessedInputFrequencyWithClusterStateCache:attributeCacheContainer.realContainer
                                                               endpoint:endpoint
                                                                  queue:queue
                                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                 // Cast is safe because subclass does not add any selectors.
                                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                                             }];
}

- (void)readAttributeWiredCurrentTypeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeWiredCurrentTypeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)
    subscribeAttributeWiredCurrentTypeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeWiredCurrentTypeWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributeWiredCurrentTypeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeWiredCurrentTypeWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeWiredAssessedCurrentWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeWiredAssessedCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeWiredAssessedCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeWiredAssessedCurrentWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSNumber *>(value), error);
                                             }];
}
+ (void)readAttributeWiredAssessedCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeWiredAssessedCurrentWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSNumber *>(value), error);
                                                      }];
}

- (void)readAttributeWiredNominalVoltageWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeWiredNominalVoltageWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeWiredNominalVoltageWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeWiredNominalVoltageWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSNumber *>(value), error);
                                            }];
}
+ (void)readAttributeWiredNominalVoltageWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeWiredNominalVoltageWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}

- (void)readAttributeWiredMaximumCurrentWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeWiredMaximumCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeWiredMaximumCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeWiredMaximumCurrentWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSNumber *>(value), error);
                                            }];
}
+ (void)readAttributeWiredMaximumCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeWiredMaximumCurrentWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}

- (void)readAttributeWiredPresentWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeWiredPresentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeWiredPresentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeWiredPresentWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributeWiredPresentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeWiredPresentWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributeActiveWiredFaultsWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeActiveWiredFaultsWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)
    subscribeAttributeActiveWiredFaultsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeActiveWiredFaultsWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSArray *>(value), error);
                                          }];
}
+ (void)readAttributeActiveWiredFaultsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeActiveWiredFaultsWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSArray *>(value), error);
                                                   }];
}

- (void)readAttributeBatVoltageWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBatVoltageWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeBatVoltageWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeBatVoltageWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeBatVoltageWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBatVoltageWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeBatPercentRemainingWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeBatPercentRemainingWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeBatPercentRemainingWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeBatPercentRemainingWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSNumber *>(value), error);
                                            }];
}
+ (void)readAttributeBatPercentRemainingWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBatPercentRemainingWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}

- (void)readAttributeBatTimeRemainingWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeBatTimeRemainingWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)
    subscribeAttributeBatTimeRemainingWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeBatTimeRemainingWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributeBatTimeRemainingWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBatTimeRemainingWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeBatChargeLevelWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeBatChargeLevelWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeBatChargeLevelWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeBatChargeLevelWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSNumber *>(value), error);
                                       }];
}
+ (void)readAttributeBatChargeLevelWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBatChargeLevelWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSNumber *>(value), error);
                                                }];
}

- (void)readAttributeBatReplacementNeededWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeBatReplacementNeededWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeBatReplacementNeededWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeBatReplacementNeededWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSNumber *>(value), error);
                                             }];
}
+ (void)readAttributeBatReplacementNeededWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBatReplacementNeededWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSNumber *>(value), error);
                                                      }];
}

- (void)readAttributeBatReplaceabilityWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeBatReplaceabilityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeBatReplaceabilityWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeBatReplaceabilityWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSNumber *>(value), error);
                                          }];
}
+ (void)readAttributeBatReplaceabilityWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBatReplaceabilityWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}

- (void)readAttributeBatPresentWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBatPresentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeBatPresentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeBatPresentWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeBatPresentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBatPresentWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeActiveBatFaultsWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeActiveBatFaultsWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeActiveBatFaultsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeActiveBatFaultsWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSArray *>(value), error);
                                        }];
}
+ (void)readAttributeActiveBatFaultsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeActiveBatFaultsWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSArray *>(value), error);
                                                 }];
}

- (void)readAttributeBatReplacementDescriptionWithCompletionHandler:(void (^)(NSString * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    [self readAttributeBatReplacementDescriptionWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)subscribeAttributeBatReplacementDescriptionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                                            params:(MTRSubscribeParams * _Nullable)params
                                           subscriptionEstablished:
                                               (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                     reportHandler:(void (^)(NSString * _Nullable value,
                                                                       NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeBatReplacementDescriptionWithParams:subscribeParams
                                        subscriptionEstablished:subscriptionEstablishedHandler
                                                  reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      reportHandler(static_cast<NSString *>(value), error);
                                                  }];
}
+ (void)readAttributeBatReplacementDescriptionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                               completionHandler:(void (^)(NSString * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    [self readAttributeBatReplacementDescriptionWithClusterStateCache:attributeCacheContainer.realContainer
                                                             endpoint:endpoint
                                                                queue:queue
                                                           completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                                               // Cast is safe because subclass does not add any selectors.
                                                               completionHandler(static_cast<NSString *>(value), error);
                                                           }];
}

- (void)readAttributeBatCommonDesignationWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeBatCommonDesignationWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeBatCommonDesignationWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeBatCommonDesignationWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSNumber *>(value), error);
                                             }];
}
+ (void)readAttributeBatCommonDesignationWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBatCommonDesignationWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSNumber *>(value), error);
                                                      }];
}

- (void)readAttributeBatANSIDesignationWithCompletionHandler:(void (^)(NSString * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    [self readAttributeBatANSIDesignationWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)subscribeAttributeBatANSIDesignationWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:
                                        (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeBatANSIDesignationWithParams:subscribeParams
                                 subscriptionEstablished:subscriptionEstablishedHandler
                                           reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               reportHandler(static_cast<NSString *>(value), error);
                                           }];
}
+ (void)readAttributeBatANSIDesignationWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBatANSIDesignationWithClusterStateCache:attributeCacheContainer.realContainer
                                                      endpoint:endpoint
                                                         queue:queue
                                                    completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                                        // Cast is safe because subclass does not add any selectors.
                                                        completionHandler(static_cast<NSString *>(value), error);
                                                    }];
}

- (void)readAttributeBatIECDesignationWithCompletionHandler:(void (^)(NSString * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeBatIECDesignationWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)subscribeAttributeBatIECDesignationWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeBatIECDesignationWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSString *>(value), error);
                                          }];
}
+ (void)readAttributeBatIECDesignationWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBatIECDesignationWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSString *>(value), error);
                                                   }];
}

- (void)readAttributeBatApprovedChemistryWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeBatApprovedChemistryWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeBatApprovedChemistryWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeBatApprovedChemistryWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSNumber *>(value), error);
                                             }];
}
+ (void)readAttributeBatApprovedChemistryWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBatApprovedChemistryWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSNumber *>(value), error);
                                                      }];
}

- (void)readAttributeBatCapacityWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBatCapacityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeBatCapacityWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeBatCapacityWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSNumber *>(value), error);
                                    }];
}
+ (void)readAttributeBatCapacityWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBatCapacityWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                             }];
}

- (void)readAttributeBatQuantityWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBatQuantityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeBatQuantityWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeBatQuantityWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSNumber *>(value), error);
                                    }];
}
+ (void)readAttributeBatQuantityWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBatQuantityWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                             }];
}

- (void)readAttributeBatChargeStateWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeBatChargeStateWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeBatChargeStateWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeBatChargeStateWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSNumber *>(value), error);
                                       }];
}
+ (void)readAttributeBatChargeStateWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBatChargeStateWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSNumber *>(value), error);
                                                }];
}

- (void)readAttributeBatTimeToFullChargeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeBatTimeToFullChargeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeBatTimeToFullChargeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeBatTimeToFullChargeWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSNumber *>(value), error);
                                            }];
}
+ (void)readAttributeBatTimeToFullChargeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBatTimeToFullChargeWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}

- (void)readAttributeBatFunctionalWhileChargingWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    [self readAttributeBatFunctionalWhileChargingWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeBatFunctionalWhileChargingWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                                             params:(MTRSubscribeParams * _Nullable)params
                                            subscriptionEstablished:
                                                (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                      reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeBatFunctionalWhileChargingWithParams:subscribeParams
                                         subscriptionEstablished:subscriptionEstablishedHandler
                                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       reportHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}
+ (void)readAttributeBatFunctionalWhileChargingWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                         endpoint:(NSNumber *)endpoint
                                                            queue:(dispatch_queue_t)queue
                                                completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    [self readAttributeBatFunctionalWhileChargingWithClusterStateCache:attributeCacheContainer.realContainer
                                                              endpoint:endpoint
                                                                 queue:queue
                                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                // Cast is safe because subclass does not add any selectors.
                                                                completionHandler(static_cast<NSNumber *>(value), error);
                                                            }];
}

- (void)readAttributeBatChargingCurrentWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    [self readAttributeBatChargingCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeBatChargingCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:
                                        (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeBatChargingCurrentWithParams:subscribeParams
                                 subscriptionEstablished:subscriptionEstablishedHandler
                                           reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               reportHandler(static_cast<NSNumber *>(value), error);
                                           }];
}
+ (void)readAttributeBatChargingCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBatChargingCurrentWithClusterStateCache:attributeCacheContainer.realContainer
                                                      endpoint:endpoint
                                                         queue:queue
                                                    completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                        // Cast is safe because subclass does not add any selectors.
                                                        completionHandler(static_cast<NSNumber *>(value), error);
                                                    }];
}

- (void)readAttributeActiveBatChargeFaultsWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    [self readAttributeActiveBatChargeFaultsWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeActiveBatChargeFaultsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeActiveBatChargeFaultsWithParams:subscribeParams
                                    subscriptionEstablished:subscriptionEstablishedHandler
                                              reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  reportHandler(static_cast<NSArray *>(value), error);
                                              }];
}
+ (void)readAttributeActiveBatChargeFaultsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeActiveBatChargeFaultsWithClusterStateCache:attributeCacheContainer.realContainer
                                                         endpoint:endpoint
                                                            queue:queue
                                                       completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                           // Cast is safe because subclass does not add any selectors.
                                                           completionHandler(static_cast<NSArray *>(value), error);
                                                       }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterGeneralCommissioning

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)armFailSafeWithParams:(MTRGeneralCommissioningClusterArmFailSafeParams *)params
                   completion:(void (^)(MTRGeneralCommissioningClusterArmFailSafeResponseParams * _Nullable data,
                                  NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRGeneralCommissioningClusterArmFailSafeResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            GeneralCommissioningClusterArmFailSafeResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRGeneralCommissioningClusterArmFailSafeResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            GeneralCommissioning::Commands::ArmFailSafe::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.expiryLengthSeconds = params.expiryLengthSeconds.unsignedShortValue;
            request.breadcrumb = params.breadcrumb.unsignedLongLongValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)setRegulatoryConfigWithParams:(MTRGeneralCommissioningClusterSetRegulatoryConfigParams *)params
                           completion:(void (^)(MTRGeneralCommissioningClusterSetRegulatoryConfigResponseParams * _Nullable data,
                                          NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRGeneralCommissioningClusterSetRegulatoryConfigResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            GeneralCommissioningClusterSetRegulatoryConfigResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRGeneralCommissioningClusterSetRegulatoryConfigResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            GeneralCommissioning::Commands::SetRegulatoryConfig::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.newRegulatoryConfig = static_cast<std::remove_reference_t<decltype(request.newRegulatoryConfig)>>(
                params.newRegulatoryConfig.unsignedCharValue);
            request.countryCode = [self asCharSpan:params.countryCode];
            request.breadcrumb = params.breadcrumb.unsignedLongLongValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)commissioningCompleteWithCompletion:(void (^)(
                                                MTRGeneralCommissioningClusterCommissioningCompleteResponseParams * _Nullable data,
                                                NSError * _Nullable error))completion
{
    [self commissioningCompleteWithParams:nil completion:completion];
}
- (void)commissioningCompleteWithParams:(MTRGeneralCommissioningClusterCommissioningCompleteParams * _Nullable)params
                             completion:
                                 (void (^)(MTRGeneralCommissioningClusterCommissioningCompleteResponseParams * _Nullable data,
                                     NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRGeneralCommissioningClusterCommissioningCompleteResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            GeneralCommissioningClusterCommissioningCompleteResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRGeneralCommissioningClusterCommissioningCompleteResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            GeneralCommissioning::Commands::CommissioningComplete::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeBreadcrumbWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = GeneralCommissioning::Attributes::Breadcrumb::TypeInfo;
    return MTRReadAttribute<MTRInt64uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeBreadcrumbWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeBreadcrumbWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeBreadcrumbWithValue:(NSNumber * _Nonnull)value
                                   params:(MTRWriteParams * _Nullable)params
                               completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = GeneralCommissioning::Attributes::Breadcrumb::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedLongLongValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeBreadcrumbWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = GeneralCommissioning::Attributes::Breadcrumb::TypeInfo;
    MTRSubscribeAttribute<MTRInt64uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeBreadcrumbWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt64uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int64uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GeneralCommissioning::Attributes::Breadcrumb::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBasicCommissioningInfoWithCompletion:
    (void (^)(MTRGeneralCommissioningClusterBasicCommissioningInfo * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = GeneralCommissioning::Attributes::BasicCommissioningInfo::TypeInfo;
    return MTRReadAttribute<MTRGeneralCommissioningBasicCommissioningInfoStructAttributeCallbackBridge,
        MTRGeneralCommissioningClusterBasicCommissioningInfo, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeBasicCommissioningInfoWithParams:(MTRSubscribeParams * _Nonnull)params
                                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                             reportHandler:
                                                 (void (^)(MTRGeneralCommissioningClusterBasicCommissioningInfo * _Nullable value,
                                                     NSError * _Nullable error))reportHandler
{
    using TypeInfo = GeneralCommissioning::Attributes::BasicCommissioningInfo::TypeInfo;
    MTRSubscribeAttribute<MTRGeneralCommissioningBasicCommissioningInfoStructAttributeCallbackSubscriptionBridge,
        MTRGeneralCommissioningClusterBasicCommissioningInfo, TypeInfo::DecodableType>(params, subscriptionEstablished,
        reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)
    readAttributeBasicCommissioningInfoWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                                  completion:
                                                      (void (^)(
                                                          MTRGeneralCommissioningClusterBasicCommissioningInfo * _Nullable value,
                                                          NSError * _Nullable error))completion
{
    auto * bridge = new MTRGeneralCommissioningBasicCommissioningInfoStructAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(GeneralCommissioningBasicCommissioningInfoStructAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GeneralCommissioning::Attributes::BasicCommissioningInfo::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRegulatoryConfigWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = GeneralCommissioning::Attributes::RegulatoryConfig::TypeInfo;
    return MTRReadAttribute<MTRGeneralCommissioningClusterRegulatoryLocationTypeEnumAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRegulatoryConfigWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = GeneralCommissioning::Attributes::RegulatoryConfig::TypeInfo;
    MTRSubscribeAttribute<MTRGeneralCommissioningClusterRegulatoryLocationTypeEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeRegulatoryConfigWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRGeneralCommissioningClusterRegulatoryLocationTypeEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(GeneralCommissioningClusterRegulatoryLocationTypeEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GeneralCommissioning::Attributes::RegulatoryConfig::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeLocationCapabilityWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = GeneralCommissioning::Attributes::LocationCapability::TypeInfo;
    return MTRReadAttribute<MTRGeneralCommissioningClusterRegulatoryLocationTypeEnumAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeLocationCapabilityWithParams:(MTRSubscribeParams * _Nonnull)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = GeneralCommissioning::Attributes::LocationCapability::TypeInfo;
    MTRSubscribeAttribute<MTRGeneralCommissioningClusterRegulatoryLocationTypeEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeLocationCapabilityWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                                  completion:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRGeneralCommissioningClusterRegulatoryLocationTypeEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(GeneralCommissioningClusterRegulatoryLocationTypeEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GeneralCommissioning::Attributes::LocationCapability::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSupportsConcurrentConnectionWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = GeneralCommissioning::Attributes::SupportsConcurrentConnection::TypeInfo;
    return MTRReadAttribute<MTRBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeSupportsConcurrentConnectionWithParams:(MTRSubscribeParams * _Nonnull)params
                                         subscriptionEstablished:
                                             (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                   reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))reportHandler
{
    using TypeInfo = GeneralCommissioning::Attributes::SupportsConcurrentConnection::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeSupportsConcurrentConnectionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                              endpoint:(NSNumber *)endpoint
                                                                 queue:(dispatch_queue_t)queue
                                                            completion:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GeneralCommissioning::Attributes::SupportsConcurrentConnection::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = GeneralCommissioning::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRGeneralCommissioningGeneratedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = GeneralCommissioning::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRGeneralCommissioningGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRGeneralCommissioningGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(GeneralCommissioningGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GeneralCommissioning::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = GeneralCommissioning::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRGeneralCommissioningAcceptedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = GeneralCommissioning::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRGeneralCommissioningAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRGeneralCommissioningAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(GeneralCommissioningAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GeneralCommissioning::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = GeneralCommissioning::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRGeneralCommissioningEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = GeneralCommissioning::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRGeneralCommissioningEventListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRGeneralCommissioningEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(GeneralCommissioningEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GeneralCommissioning::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = GeneralCommissioning::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRGeneralCommissioningAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = GeneralCommissioning::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRGeneralCommissioningAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRGeneralCommissioningAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(GeneralCommissioningAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GeneralCommissioning::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = GeneralCommissioning::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = GeneralCommissioning::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GeneralCommissioning::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = GeneralCommissioning::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = GeneralCommissioning::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GeneralCommissioning::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterGeneralCommissioning (Deprecated)

- (void)armFailSafeWithParams:(MTRGeneralCommissioningClusterArmFailSafeParams *)params
            completionHandler:(void (^)(MTRGeneralCommissioningClusterArmFailSafeResponseParams * _Nullable data,
                                  NSError * _Nullable error))completionHandler
{
    [self armFailSafeWithParams:params
                     completion:^(
                         MTRGeneralCommissioningClusterArmFailSafeResponseParams * _Nullable data, NSError * _Nullable error) {
                         // Cast is safe because subclass does not add any selectors.
                         completionHandler(static_cast<MTRGeneralCommissioningClusterArmFailSafeResponseParams *>(data), error);
                     }];
}
- (void)setRegulatoryConfigWithParams:(MTRGeneralCommissioningClusterSetRegulatoryConfigParams *)params
                    completionHandler:(void (^)(MTRGeneralCommissioningClusterSetRegulatoryConfigResponseParams * _Nullable data,
                                          NSError * _Nullable error))completionHandler
{
    [self setRegulatoryConfigWithParams:params
                             completion:^(MTRGeneralCommissioningClusterSetRegulatoryConfigResponseParams * _Nullable data,
                                 NSError * _Nullable error) {
                                 // Cast is safe because subclass does not add any selectors.
                                 completionHandler(
                                     static_cast<MTRGeneralCommissioningClusterSetRegulatoryConfigResponseParams *>(data), error);
                             }];
}
- (void)commissioningCompleteWithParams:(MTRGeneralCommissioningClusterCommissioningCompleteParams * _Nullable)params
                      completionHandler:
                          (void (^)(MTRGeneralCommissioningClusterCommissioningCompleteResponseParams * _Nullable data,
                              NSError * _Nullable error))completionHandler
{
    [self
        commissioningCompleteWithParams:params
                             completion:^(MTRGeneralCommissioningClusterCommissioningCompleteResponseParams * _Nullable data,
                                 NSError * _Nullable error) {
                                 // Cast is safe because subclass does not add any selectors.
                                 completionHandler(
                                     static_cast<MTRGeneralCommissioningClusterCommissioningCompleteResponseParams *>(data), error);
                             }];
}
- (void)commissioningCompleteWithCompletionHandler:
    (void (^)(MTRGeneralCommissioningClusterCommissioningCompleteResponseParams * _Nullable data,
        NSError * _Nullable error))completionHandler
{
    [self commissioningCompleteWithParams:nil completionHandler:completionHandler];
}

- (void)readAttributeBreadcrumbWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBreadcrumbWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeBreadcrumbWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeBreadcrumbWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeBreadcrumbWithValue:(NSNumber * _Nonnull)value
                                   params:(MTRWriteParams * _Nullable)params
                        completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeBreadcrumbWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeBreadcrumbWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeBreadcrumbWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeBreadcrumbWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBreadcrumbWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeBasicCommissioningInfoWithCompletionHandler:
    (void (^)(MTRGeneralCommissioningClusterBasicCommissioningInfo * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBasicCommissioningInfoWithCompletion:^(
        MTRGeneralCommissioningClusterBasicCommissioningInfo * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<MTRGeneralCommissioningClusterBasicCommissioningInfo *>(value), error);
    }];
}
- (void)subscribeAttributeBasicCommissioningInfoWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                                         params:(MTRSubscribeParams * _Nullable)params
                                        subscriptionEstablished:
                                            (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                  reportHandler:
                                                      (void (^)(
                                                          MTRGeneralCommissioningClusterBasicCommissioningInfo * _Nullable value,
                                                          NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self
        subscribeAttributeBasicCommissioningInfoWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(MTRGeneralCommissioningClusterBasicCommissioningInfo * _Nullable value,
                                                 NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(
                                                     static_cast<MTRGeneralCommissioningClusterBasicCommissioningInfo *>(value),
                                                     error);
                                             }];
}
+ (void)readAttributeBasicCommissioningInfoWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                            completionHandler:
                                                (void (^)(MTRGeneralCommissioningClusterBasicCommissioningInfo * _Nullable value,
                                                    NSError * _Nullable error))completionHandler
{
    [self readAttributeBasicCommissioningInfoWithClusterStateCache:attributeCacheContainer.realContainer
                                                          endpoint:endpoint
                                                             queue:queue
                                                        completion:^(
                                                            MTRGeneralCommissioningClusterBasicCommissioningInfo * _Nullable value,
                                                            NSError * _Nullable error) {
                                                            // Cast is safe because subclass does not add any selectors.
                                                            completionHandler(
                                                                static_cast<MTRGeneralCommissioningClusterBasicCommissioningInfo *>(
                                                                    value),
                                                                error);
                                                        }];
}

- (void)readAttributeRegulatoryConfigWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeRegulatoryConfigWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)
    subscribeAttributeRegulatoryConfigWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRegulatoryConfigWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributeRegulatoryConfigWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRegulatoryConfigWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeLocationCapabilityWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    [self readAttributeLocationCapabilityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeLocationCapabilityWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:
                                        (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeLocationCapabilityWithParams:subscribeParams
                                 subscriptionEstablished:subscriptionEstablishedHandler
                                           reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               reportHandler(static_cast<NSNumber *>(value), error);
                                           }];
}
+ (void)readAttributeLocationCapabilityWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLocationCapabilityWithClusterStateCache:attributeCacheContainer.realContainer
                                                      endpoint:endpoint
                                                         queue:queue
                                                    completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                        // Cast is safe because subclass does not add any selectors.
                                                        completionHandler(static_cast<NSNumber *>(value), error);
                                                    }];
}

- (void)readAttributeSupportsConcurrentConnectionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completionHandler
{
    [self readAttributeSupportsConcurrentConnectionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeSupportsConcurrentConnectionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                                               params:(MTRSubscribeParams * _Nullable)params
                                              subscriptionEstablished:
                                                  (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                        reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeSupportsConcurrentConnectionWithParams:subscribeParams
                                           subscriptionEstablished:subscriptionEstablishedHandler
                                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         reportHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}
+ (void)readAttributeSupportsConcurrentConnectionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                           endpoint:(NSNumber *)endpoint
                                                              queue:(dispatch_queue_t)queue
                                                  completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    [self readAttributeSupportsConcurrentConnectionWithClusterStateCache:attributeCacheContainer.realContainer
                                                                endpoint:endpoint
                                                                   queue:queue
                                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                  // Cast is safe because subclass does not add any selectors.
                                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                                              }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterNetworkCommissioning

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)scanNetworksWithParams:(MTRNetworkCommissioningClusterScanNetworksParams * _Nullable)params
                    completion:(void (^)(MTRNetworkCommissioningClusterScanNetworksResponseParams * _Nullable data,
                                   NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRNetworkCommissioningClusterScanNetworksResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            NetworkCommissioningClusterScanNetworksResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRNetworkCommissioningClusterScanNetworksResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            NetworkCommissioning::Commands::ScanNetworks::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            if (params != nil) {
                if (params.ssid != nil) {
                    auto & definedValue_0 = request.ssid.Emplace();
                    if (params.ssid == nil) {
                        definedValue_0.SetNull();
                    } else {
                        auto & nonNullValue_1 = definedValue_0.SetNonNull();
                        nonNullValue_1 = [self asByteSpan:params.ssid];
                    }
                }
                if (params.breadcrumb != nil) {
                    auto & definedValue_0 = request.breadcrumb.Emplace();
                    definedValue_0 = params.breadcrumb.unsignedLongLongValue;
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)addOrUpdateWiFiNetworkWithParams:(MTRNetworkCommissioningClusterAddOrUpdateWiFiNetworkParams *)params
                              completion:(void (^)(MTRNetworkCommissioningClusterNetworkConfigResponseParams * _Nullable data,
                                             NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRNetworkCommissioningClusterNetworkConfigResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            NetworkCommissioningClusterNetworkConfigResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRNetworkCommissioningClusterNetworkConfigResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            NetworkCommissioning::Commands::AddOrUpdateWiFiNetwork::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.ssid = [self asByteSpan:params.ssid];
            request.credentials = [self asByteSpan:params.credentials];
            if (params.breadcrumb != nil) {
                auto & definedValue_0 = request.breadcrumb.Emplace();
                definedValue_0 = params.breadcrumb.unsignedLongLongValue;
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)addOrUpdateThreadNetworkWithParams:(MTRNetworkCommissioningClusterAddOrUpdateThreadNetworkParams *)params
                                completion:(void (^)(MTRNetworkCommissioningClusterNetworkConfigResponseParams * _Nullable data,
                                               NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRNetworkCommissioningClusterNetworkConfigResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            NetworkCommissioningClusterNetworkConfigResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRNetworkCommissioningClusterNetworkConfigResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            NetworkCommissioning::Commands::AddOrUpdateThreadNetwork::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.operationalDataset = [self asByteSpan:params.operationalDataset];
            if (params.breadcrumb != nil) {
                auto & definedValue_0 = request.breadcrumb.Emplace();
                definedValue_0 = params.breadcrumb.unsignedLongLongValue;
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)removeNetworkWithParams:(MTRNetworkCommissioningClusterRemoveNetworkParams *)params
                     completion:(void (^)(MTRNetworkCommissioningClusterNetworkConfigResponseParams * _Nullable data,
                                    NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRNetworkCommissioningClusterNetworkConfigResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            NetworkCommissioningClusterNetworkConfigResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRNetworkCommissioningClusterNetworkConfigResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            NetworkCommissioning::Commands::RemoveNetwork::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.networkID = [self asByteSpan:params.networkID];
            if (params.breadcrumb != nil) {
                auto & definedValue_0 = request.breadcrumb.Emplace();
                definedValue_0 = params.breadcrumb.unsignedLongLongValue;
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)connectNetworkWithParams:(MTRNetworkCommissioningClusterConnectNetworkParams *)params
                      completion:(void (^)(MTRNetworkCommissioningClusterConnectNetworkResponseParams * _Nullable data,
                                     NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRNetworkCommissioningClusterConnectNetworkResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            NetworkCommissioningClusterConnectNetworkResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRNetworkCommissioningClusterConnectNetworkResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            NetworkCommissioning::Commands::ConnectNetwork::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.networkID = [self asByteSpan:params.networkID];
            if (params.breadcrumb != nil) {
                auto & definedValue_0 = request.breadcrumb.Emplace();
                definedValue_0 = params.breadcrumb.unsignedLongLongValue;
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)reorderNetworkWithParams:(MTRNetworkCommissioningClusterReorderNetworkParams *)params
                      completion:(void (^)(MTRNetworkCommissioningClusterNetworkConfigResponseParams * _Nullable data,
                                     NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRNetworkCommissioningClusterNetworkConfigResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            NetworkCommissioningClusterNetworkConfigResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRNetworkCommissioningClusterNetworkConfigResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            NetworkCommissioning::Commands::ReorderNetwork::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.networkID = [self asByteSpan:params.networkID];
            request.networkIndex = params.networkIndex.unsignedCharValue;
            if (params.breadcrumb != nil) {
                auto & definedValue_0 = request.breadcrumb.Emplace();
                definedValue_0 = params.breadcrumb.unsignedLongLongValue;
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeMaxNetworksWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = NetworkCommissioning::Attributes::MaxNetworks::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMaxNetworksWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = NetworkCommissioning::Attributes::MaxNetworks::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMaxNetworksWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = NetworkCommissioning::Attributes::MaxNetworks::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNetworksWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = NetworkCommissioning::Attributes::Networks::TypeInfo;
    return MTRReadAttribute<MTRNetworkCommissioningNetworksListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeNetworksWithParams:(MTRSubscribeParams * _Nonnull)params
                     subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                               reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = NetworkCommissioning::Attributes::Networks::TypeInfo;
    MTRSubscribeAttribute<MTRNetworkCommissioningNetworksListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNetworksWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                        completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNetworkCommissioningNetworksListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(NetworkCommissioningNetworksListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = NetworkCommissioning::Attributes::Networks::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeScanMaxTimeSecondsWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = NetworkCommissioning::Attributes::ScanMaxTimeSeconds::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeScanMaxTimeSecondsWithParams:(MTRSubscribeParams * _Nonnull)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = NetworkCommissioning::Attributes::ScanMaxTimeSeconds::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeScanMaxTimeSecondsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                                  completion:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = NetworkCommissioning::Attributes::ScanMaxTimeSeconds::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeConnectMaxTimeSecondsWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = NetworkCommissioning::Attributes::ConnectMaxTimeSeconds::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeConnectMaxTimeSecondsWithParams:(MTRSubscribeParams * _Nonnull)params
                                  subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = NetworkCommissioning::Attributes::ConnectMaxTimeSeconds::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeConnectMaxTimeSecondsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                                     completion:
                                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = NetworkCommissioning::Attributes::ConnectMaxTimeSeconds::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeInterfaceEnabledWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = NetworkCommissioning::Attributes::InterfaceEnabled::TypeInfo;
    return MTRReadAttribute<MTRBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeInterfaceEnabledWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeInterfaceEnabledWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeInterfaceEnabledWithValue:(NSNumber * _Nonnull)value
                                         params:(MTRWriteParams * _Nullable)params
                                     completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = NetworkCommissioning::Attributes::InterfaceEnabled::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.boolValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeInterfaceEnabledWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = NetworkCommissioning::Attributes::InterfaceEnabled::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeInterfaceEnabledWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = NetworkCommissioning::Attributes::InterfaceEnabled::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeLastNetworkingStatusWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = NetworkCommissioning::Attributes::LastNetworkingStatus::TypeInfo;
    return MTRReadAttribute<MTRNullableNetworkCommissioningClusterNetworkCommissioningStatusAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeLastNetworkingStatusWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = NetworkCommissioning::Attributes::LastNetworkingStatus::TypeInfo;
    MTRSubscribeAttribute<MTRNullableNetworkCommissioningClusterNetworkCommissioningStatusAttributeCallbackSubscriptionBridge,
        NSNumber, TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device,
        self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeLastNetworkingStatusWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableNetworkCommissioningClusterNetworkCommissioningStatusAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(NullableNetworkCommissioningClusterNetworkCommissioningStatusAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = NetworkCommissioning::Attributes::LastNetworkingStatus::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeLastNetworkIDWithCompletion:(void (^)(NSData * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = NetworkCommissioning::Attributes::LastNetworkID::TypeInfo;
    return MTRReadAttribute<MTRNullableOctetStringAttributeCallbackBridge, NSData, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeLastNetworkIDWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSData * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = NetworkCommissioning::Attributes::LastNetworkID::TypeInfo;
    MTRSubscribeAttribute<MTRNullableOctetStringAttributeCallbackSubscriptionBridge, NSData, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeLastNetworkIDWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSData * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableOctetStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableOctetStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = NetworkCommissioning::Attributes::LastNetworkID::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeLastConnectErrorValueWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = NetworkCommissioning::Attributes::LastConnectErrorValue::TypeInfo;
    return MTRReadAttribute<MTRNullableInt32sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeLastConnectErrorValueWithParams:(MTRSubscribeParams * _Nonnull)params
                                  subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = NetworkCommissioning::Attributes::LastConnectErrorValue::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt32sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeLastConnectErrorValueWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                                     completion:
                                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt32sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt32sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = NetworkCommissioning::Attributes::LastConnectErrorValue::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = NetworkCommissioning::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRNetworkCommissioningGeneratedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = NetworkCommissioning::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRNetworkCommissioningGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNetworkCommissioningGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(NetworkCommissioningGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = NetworkCommissioning::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = NetworkCommissioning::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRNetworkCommissioningAcceptedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = NetworkCommissioning::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRNetworkCommissioningAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNetworkCommissioningAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(NetworkCommissioningAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = NetworkCommissioning::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = NetworkCommissioning::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRNetworkCommissioningEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = NetworkCommissioning::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRNetworkCommissioningEventListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNetworkCommissioningEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(NetworkCommissioningEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = NetworkCommissioning::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = NetworkCommissioning::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRNetworkCommissioningAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = NetworkCommissioning::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRNetworkCommissioningAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNetworkCommissioningAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(NetworkCommissioningAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = NetworkCommissioning::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = NetworkCommissioning::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = NetworkCommissioning::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = NetworkCommissioning::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = NetworkCommissioning::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = NetworkCommissioning::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = NetworkCommissioning::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterNetworkCommissioning (Deprecated)

- (void)scanNetworksWithParams:(MTRNetworkCommissioningClusterScanNetworksParams * _Nullable)params
             completionHandler:(void (^)(MTRNetworkCommissioningClusterScanNetworksResponseParams * _Nullable data,
                                   NSError * _Nullable error))completionHandler
{
    [self scanNetworksWithParams:params
                      completion:^(
                          MTRNetworkCommissioningClusterScanNetworksResponseParams * _Nullable data, NSError * _Nullable error) {
                          // Cast is safe because subclass does not add any selectors.
                          completionHandler(static_cast<MTRNetworkCommissioningClusterScanNetworksResponseParams *>(data), error);
                      }];
}
- (void)addOrUpdateWiFiNetworkWithParams:(MTRNetworkCommissioningClusterAddOrUpdateWiFiNetworkParams *)params
                       completionHandler:(void (^)(MTRNetworkCommissioningClusterNetworkConfigResponseParams * _Nullable data,
                                             NSError * _Nullable error))completionHandler
{
    [self addOrUpdateWiFiNetworkWithParams:params
                                completion:^(MTRNetworkCommissioningClusterNetworkConfigResponseParams * _Nullable data,
                                    NSError * _Nullable error) {
                                    // Cast is safe because subclass does not add any selectors.
                                    completionHandler(
                                        static_cast<MTRNetworkCommissioningClusterNetworkConfigResponseParams *>(data), error);
                                }];
}
- (void)addOrUpdateThreadNetworkWithParams:(MTRNetworkCommissioningClusterAddOrUpdateThreadNetworkParams *)params
                         completionHandler:(void (^)(MTRNetworkCommissioningClusterNetworkConfigResponseParams * _Nullable data,
                                               NSError * _Nullable error))completionHandler
{
    [self addOrUpdateThreadNetworkWithParams:params
                                  completion:^(MTRNetworkCommissioningClusterNetworkConfigResponseParams * _Nullable data,
                                      NSError * _Nullable error) {
                                      // Cast is safe because subclass does not add any selectors.
                                      completionHandler(
                                          static_cast<MTRNetworkCommissioningClusterNetworkConfigResponseParams *>(data), error);
                                  }];
}
- (void)removeNetworkWithParams:(MTRNetworkCommissioningClusterRemoveNetworkParams *)params
              completionHandler:(void (^)(MTRNetworkCommissioningClusterNetworkConfigResponseParams * _Nullable data,
                                    NSError * _Nullable error))completionHandler
{
    [self removeNetworkWithParams:params
                       completion:^(
                           MTRNetworkCommissioningClusterNetworkConfigResponseParams * _Nullable data, NSError * _Nullable error) {
                           // Cast is safe because subclass does not add any selectors.
                           completionHandler(static_cast<MTRNetworkCommissioningClusterNetworkConfigResponseParams *>(data), error);
                       }];
}
- (void)connectNetworkWithParams:(MTRNetworkCommissioningClusterConnectNetworkParams *)params
               completionHandler:(void (^)(MTRNetworkCommissioningClusterConnectNetworkResponseParams * _Nullable data,
                                     NSError * _Nullable error))completionHandler
{
    [self
        connectNetworkWithParams:params
                      completion:^(
                          MTRNetworkCommissioningClusterConnectNetworkResponseParams * _Nullable data, NSError * _Nullable error) {
                          // Cast is safe because subclass does not add any selectors.
                          completionHandler(static_cast<MTRNetworkCommissioningClusterConnectNetworkResponseParams *>(data), error);
                      }];
}
- (void)reorderNetworkWithParams:(MTRNetworkCommissioningClusterReorderNetworkParams *)params
               completionHandler:(void (^)(MTRNetworkCommissioningClusterNetworkConfigResponseParams * _Nullable data,
                                     NSError * _Nullable error))completionHandler
{
    [self
        reorderNetworkWithParams:params
                      completion:^(
                          MTRNetworkCommissioningClusterNetworkConfigResponseParams * _Nullable data, NSError * _Nullable error) {
                          // Cast is safe because subclass does not add any selectors.
                          completionHandler(static_cast<MTRNetworkCommissioningClusterNetworkConfigResponseParams *>(data), error);
                      }];
}

- (void)readAttributeMaxNetworksWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxNetworksWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeMaxNetworksWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMaxNetworksWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSNumber *>(value), error);
                                    }];
}
+ (void)readAttributeMaxNetworksWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxNetworksWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                             }];
}

- (void)readAttributeNetworksWithCompletionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNetworksWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeNetworksWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNetworksWithParams:subscribeParams
                       subscriptionEstablished:subscriptionEstablishedHandler
                                 reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                     // Cast is safe because subclass does not add any selectors.
                                     reportHandler(static_cast<NSArray *>(value), error);
                                 }];
}
+ (void)readAttributeNetworksWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNetworksWithClusterStateCache:attributeCacheContainer.realContainer
                                            endpoint:endpoint
                                               queue:queue
                                          completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              completionHandler(static_cast<NSArray *>(value), error);
                                          }];
}

- (void)readAttributeScanMaxTimeSecondsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    [self readAttributeScanMaxTimeSecondsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeScanMaxTimeSecondsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:
                                        (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeScanMaxTimeSecondsWithParams:subscribeParams
                                 subscriptionEstablished:subscriptionEstablishedHandler
                                           reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               reportHandler(static_cast<NSNumber *>(value), error);
                                           }];
}
+ (void)readAttributeScanMaxTimeSecondsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeScanMaxTimeSecondsWithClusterStateCache:attributeCacheContainer.realContainer
                                                      endpoint:endpoint
                                                         queue:queue
                                                    completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                        // Cast is safe because subclass does not add any selectors.
                                                        completionHandler(static_cast<NSNumber *>(value), error);
                                                    }];
}

- (void)readAttributeConnectMaxTimeSecondsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    [self readAttributeConnectMaxTimeSecondsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeConnectMaxTimeSecondsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeConnectMaxTimeSecondsWithParams:subscribeParams
                                    subscriptionEstablished:subscriptionEstablishedHandler
                                              reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  reportHandler(static_cast<NSNumber *>(value), error);
                                              }];
}
+ (void)readAttributeConnectMaxTimeSecondsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeConnectMaxTimeSecondsWithClusterStateCache:attributeCacheContainer.realContainer
                                                         endpoint:endpoint
                                                            queue:queue
                                                       completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                           // Cast is safe because subclass does not add any selectors.
                                                           completionHandler(static_cast<NSNumber *>(value), error);
                                                       }];
}

- (void)readAttributeInterfaceEnabledWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeInterfaceEnabledWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeInterfaceEnabledWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeInterfaceEnabledWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeInterfaceEnabledWithValue:(NSNumber * _Nonnull)value
                                         params:(MTRWriteParams * _Nullable)params
                              completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeInterfaceEnabledWithValue:value params:params completion:completionHandler];
}
- (void)
    subscribeAttributeInterfaceEnabledWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeInterfaceEnabledWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributeInterfaceEnabledWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInterfaceEnabledWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeLastNetworkingStatusWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeLastNetworkingStatusWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeLastNetworkingStatusWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeLastNetworkingStatusWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSNumber *>(value), error);
                                             }];
}
+ (void)readAttributeLastNetworkingStatusWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLastNetworkingStatusWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSNumber *>(value), error);
                                                      }];
}

- (void)readAttributeLastNetworkIDWithCompletionHandler:(void (^)(
                                                            NSData * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLastNetworkIDWithCompletion:^(NSData * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSData *>(value), error);
    }];
}
- (void)subscribeAttributeLastNetworkIDWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSData * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeLastNetworkIDWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSData * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSData *>(value), error);
                                      }];
}
+ (void)readAttributeLastNetworkIDWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSData * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLastNetworkIDWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSData * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSData *>(value), error);
                                               }];
}

- (void)readAttributeLastConnectErrorValueWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    [self readAttributeLastConnectErrorValueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeLastConnectErrorValueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeLastConnectErrorValueWithParams:subscribeParams
                                    subscriptionEstablished:subscriptionEstablishedHandler
                                              reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  reportHandler(static_cast<NSNumber *>(value), error);
                                              }];
}
+ (void)readAttributeLastConnectErrorValueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLastConnectErrorValueWithClusterStateCache:attributeCacheContainer.realContainer
                                                         endpoint:endpoint
                                                            queue:queue
                                                       completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                           // Cast is safe because subclass does not add any selectors.
                                                           completionHandler(static_cast<NSNumber *>(value), error);
                                                       }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterDiagnosticLogs

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)retrieveLogsRequestWithParams:(MTRDiagnosticLogsClusterRetrieveLogsRequestParams *)params
                           completion:(void (^)(MTRDiagnosticLogsClusterRetrieveLogsResponseParams * _Nullable data,
                                          NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRDiagnosticLogsClusterRetrieveLogsResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            DiagnosticLogsClusterRetrieveLogsResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRDiagnosticLogsClusterRetrieveLogsResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            DiagnosticLogs::Commands::RetrieveLogsRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.intent = static_cast<std::remove_reference_t<decltype(request.intent)>>(params.intent.unsignedCharValue);
            request.requestedProtocol = static_cast<std::remove_reference_t<decltype(request.requestedProtocol)>>(
                params.requestedProtocol.unsignedCharValue);
            if (params.transferFileDesignator != nil) {
                auto & definedValue_0 = request.transferFileDesignator.Emplace();
                definedValue_0 = [self asCharSpan:params.transferFileDesignator];
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DiagnosticLogs::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRDiagnosticLogsGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = DiagnosticLogs::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRDiagnosticLogsGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRDiagnosticLogsGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(DiagnosticLogsGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DiagnosticLogs::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DiagnosticLogs::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRDiagnosticLogsAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = DiagnosticLogs::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRDiagnosticLogsAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRDiagnosticLogsAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(DiagnosticLogsAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DiagnosticLogs::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DiagnosticLogs::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRDiagnosticLogsEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = DiagnosticLogs::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRDiagnosticLogsEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRDiagnosticLogsEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(DiagnosticLogsEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DiagnosticLogs::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DiagnosticLogs::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRDiagnosticLogsAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = DiagnosticLogs::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRDiagnosticLogsAttributeListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRDiagnosticLogsAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(DiagnosticLogsAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DiagnosticLogs::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DiagnosticLogs::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = DiagnosticLogs::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DiagnosticLogs::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DiagnosticLogs::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = DiagnosticLogs::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DiagnosticLogs::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterDiagnosticLogs (Deprecated)

- (void)retrieveLogsRequestWithParams:(MTRDiagnosticLogsClusterRetrieveLogsRequestParams *)params
                    completionHandler:(void (^)(MTRDiagnosticLogsClusterRetrieveLogsResponseParams * _Nullable data,
                                          NSError * _Nullable error))completionHandler
{
    [self retrieveLogsRequestWithParams:params
                             completion:^(
                                 MTRDiagnosticLogsClusterRetrieveLogsResponseParams * _Nullable data, NSError * _Nullable error) {
                                 // Cast is safe because subclass does not add any selectors.
                                 completionHandler(static_cast<MTRDiagnosticLogsClusterRetrieveLogsResponseParams *>(data), error);
                             }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterGeneralDiagnostics

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)testEventTriggerWithParams:(MTRGeneralDiagnosticsClusterTestEventTriggerParams *)params
                        completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            GeneralDiagnostics::Commands::TestEventTrigger::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.enableKey = [self asByteSpan:params.enableKey];
            request.eventTrigger = params.eventTrigger.unsignedLongLongValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeNetworkInterfacesWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = GeneralDiagnostics::Attributes::NetworkInterfaces::TypeInfo;
    return MTRReadAttribute<MTRGeneralDiagnosticsNetworkInterfacesListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeNetworkInterfacesWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = GeneralDiagnostics::Attributes::NetworkInterfaces::TypeInfo;
    MTRSubscribeAttribute<MTRGeneralDiagnosticsNetworkInterfacesListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeNetworkInterfacesWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRGeneralDiagnosticsNetworkInterfacesListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(GeneralDiagnosticsNetworkInterfacesListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GeneralDiagnostics::Attributes::NetworkInterfaces::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRebootCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = GeneralDiagnostics::Attributes::RebootCount::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRebootCountWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = GeneralDiagnostics::Attributes::RebootCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRebootCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GeneralDiagnostics::Attributes::RebootCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeUpTimeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = GeneralDiagnostics::Attributes::UpTime::TypeInfo;
    return MTRReadAttribute<MTRInt64uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeUpTimeWithParams:(MTRSubscribeParams * _Nonnull)params
                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                             reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = GeneralDiagnostics::Attributes::UpTime::TypeInfo;
    MTRSubscribeAttribute<MTRInt64uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeUpTimeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                                      completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt64uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int64uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GeneralDiagnostics::Attributes::UpTime::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeTotalOperationalHoursWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = GeneralDiagnostics::Attributes::TotalOperationalHours::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeTotalOperationalHoursWithParams:(MTRSubscribeParams * _Nonnull)params
                                  subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = GeneralDiagnostics::Attributes::TotalOperationalHours::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeTotalOperationalHoursWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                                     completion:
                                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GeneralDiagnostics::Attributes::TotalOperationalHours::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBootReasonWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = GeneralDiagnostics::Attributes::BootReason::TypeInfo;
    return MTRReadAttribute<MTRGeneralDiagnosticsClusterBootReasonEnumAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeBootReasonWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = GeneralDiagnostics::Attributes::BootReason::TypeInfo;
    MTRSubscribeAttribute<MTRGeneralDiagnosticsClusterBootReasonEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeBootReasonWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRGeneralDiagnosticsClusterBootReasonEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(GeneralDiagnosticsClusterBootReasonEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GeneralDiagnostics::Attributes::BootReason::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeActiveHardwareFaultsWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = GeneralDiagnostics::Attributes::ActiveHardwareFaults::TypeInfo;
    return MTRReadAttribute<MTRGeneralDiagnosticsActiveHardwareFaultsListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeActiveHardwareFaultsWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = GeneralDiagnostics::Attributes::ActiveHardwareFaults::TypeInfo;
    MTRSubscribeAttribute<MTRGeneralDiagnosticsActiveHardwareFaultsListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeActiveHardwareFaultsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRGeneralDiagnosticsActiveHardwareFaultsListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(GeneralDiagnosticsActiveHardwareFaultsListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GeneralDiagnostics::Attributes::ActiveHardwareFaults::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeActiveRadioFaultsWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = GeneralDiagnostics::Attributes::ActiveRadioFaults::TypeInfo;
    return MTRReadAttribute<MTRGeneralDiagnosticsActiveRadioFaultsListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeActiveRadioFaultsWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = GeneralDiagnostics::Attributes::ActiveRadioFaults::TypeInfo;
    MTRSubscribeAttribute<MTRGeneralDiagnosticsActiveRadioFaultsListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeActiveRadioFaultsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRGeneralDiagnosticsActiveRadioFaultsListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(GeneralDiagnosticsActiveRadioFaultsListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GeneralDiagnostics::Attributes::ActiveRadioFaults::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeActiveNetworkFaultsWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = GeneralDiagnostics::Attributes::ActiveNetworkFaults::TypeInfo;
    return MTRReadAttribute<MTRGeneralDiagnosticsActiveNetworkFaultsListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeActiveNetworkFaultsWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = GeneralDiagnostics::Attributes::ActiveNetworkFaults::TypeInfo;
    MTRSubscribeAttribute<MTRGeneralDiagnosticsActiveNetworkFaultsListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeActiveNetworkFaultsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRGeneralDiagnosticsActiveNetworkFaultsListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(GeneralDiagnosticsActiveNetworkFaultsListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GeneralDiagnostics::Attributes::ActiveNetworkFaults::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeTestEventTriggersEnabledWithCompletion:(void (^)(
                                                                NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = GeneralDiagnostics::Attributes::TestEventTriggersEnabled::TypeInfo;
    return MTRReadAttribute<MTRBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeTestEventTriggersEnabledWithParams:(MTRSubscribeParams * _Nonnull)params
                                     subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = GeneralDiagnostics::Attributes::TestEventTriggersEnabled::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeTestEventTriggersEnabledWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                          endpoint:(NSNumber *)endpoint
                                                             queue:(dispatch_queue_t)queue
                                                        completion:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GeneralDiagnostics::Attributes::TestEventTriggersEnabled::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = GeneralDiagnostics::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRGeneralDiagnosticsGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = GeneralDiagnostics::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRGeneralDiagnosticsGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRGeneralDiagnosticsGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(GeneralDiagnosticsGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GeneralDiagnostics::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = GeneralDiagnostics::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRGeneralDiagnosticsAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = GeneralDiagnostics::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRGeneralDiagnosticsAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRGeneralDiagnosticsAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(GeneralDiagnosticsAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GeneralDiagnostics::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = GeneralDiagnostics::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRGeneralDiagnosticsEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = GeneralDiagnostics::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRGeneralDiagnosticsEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRGeneralDiagnosticsEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(GeneralDiagnosticsEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GeneralDiagnostics::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = GeneralDiagnostics::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRGeneralDiagnosticsAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = GeneralDiagnostics::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRGeneralDiagnosticsAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRGeneralDiagnosticsAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(GeneralDiagnosticsAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GeneralDiagnostics::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = GeneralDiagnostics::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = GeneralDiagnostics::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GeneralDiagnostics::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = GeneralDiagnostics::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = GeneralDiagnostics::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GeneralDiagnostics::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterGeneralDiagnostics (Deprecated)

- (void)testEventTriggerWithParams:(MTRGeneralDiagnosticsClusterTestEventTriggerParams *)params
                 completionHandler:(MTRStatusCompletion)completionHandler
{
    [self testEventTriggerWithParams:params completion:completionHandler];
}

- (void)readAttributeNetworkInterfacesWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeNetworkInterfacesWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)
    subscribeAttributeNetworkInterfacesWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNetworkInterfacesWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSArray *>(value), error);
                                          }];
}
+ (void)readAttributeNetworkInterfacesWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNetworkInterfacesWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSArray *>(value), error);
                                                   }];
}

- (void)readAttributeRebootCountWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRebootCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRebootCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRebootCountWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSNumber *>(value), error);
                                    }];
}
+ (void)readAttributeRebootCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRebootCountWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                             }];
}

- (void)readAttributeUpTimeWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeUpTimeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeUpTimeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeUpTimeWithParams:subscribeParams
                     subscriptionEstablished:subscriptionEstablishedHandler
                               reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                   // Cast is safe because subclass does not add any selectors.
                                   reportHandler(static_cast<NSNumber *>(value), error);
                               }];
}
+ (void)readAttributeUpTimeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeUpTimeWithClusterStateCache:attributeCacheContainer.realContainer
                                          endpoint:endpoint
                                             queue:queue
                                        completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            completionHandler(static_cast<NSNumber *>(value), error);
                                        }];
}

- (void)readAttributeTotalOperationalHoursWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    [self readAttributeTotalOperationalHoursWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeTotalOperationalHoursWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeTotalOperationalHoursWithParams:subscribeParams
                                    subscriptionEstablished:subscriptionEstablishedHandler
                                              reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  reportHandler(static_cast<NSNumber *>(value), error);
                                              }];
}
+ (void)readAttributeTotalOperationalHoursWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeTotalOperationalHoursWithClusterStateCache:attributeCacheContainer.realContainer
                                                         endpoint:endpoint
                                                            queue:queue
                                                       completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                           // Cast is safe because subclass does not add any selectors.
                                                           completionHandler(static_cast<NSNumber *>(value), error);
                                                       }];
}

- (void)readAttributeBootReasonsWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBootReasonWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeBootReasonsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeBootReasonWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeBootReasonsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBootReasonWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeActiveHardwareFaultsWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeActiveHardwareFaultsWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeActiveHardwareFaultsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeActiveHardwareFaultsWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeActiveHardwareFaultsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeActiveHardwareFaultsWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeActiveRadioFaultsWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeActiveRadioFaultsWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)
    subscribeAttributeActiveRadioFaultsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeActiveRadioFaultsWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSArray *>(value), error);
                                          }];
}
+ (void)readAttributeActiveRadioFaultsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeActiveRadioFaultsWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSArray *>(value), error);
                                                   }];
}

- (void)readAttributeActiveNetworkFaultsWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeActiveNetworkFaultsWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeActiveNetworkFaultsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeActiveNetworkFaultsWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeActiveNetworkFaultsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeActiveNetworkFaultsWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeTestEventTriggersEnabledWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completionHandler
{
    [self readAttributeTestEventTriggersEnabledWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeTestEventTriggersEnabledWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                                           params:(MTRSubscribeParams * _Nullable)params
                                          subscriptionEstablished:
                                              (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                    reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeTestEventTriggersEnabledWithParams:subscribeParams
                                       subscriptionEstablished:subscriptionEstablishedHandler
                                                 reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     reportHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}
+ (void)readAttributeTestEventTriggersEnabledWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                              completionHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeTestEventTriggersEnabledWithClusterStateCache:attributeCacheContainer.realContainer
                                                            endpoint:endpoint
                                                               queue:queue
                                                          completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                              // Cast is safe because subclass does not add any selectors.
                                                              completionHandler(static_cast<NSNumber *>(value), error);
                                                          }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterSoftwareDiagnostics

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)resetWatermarksWithCompletion:(MTRStatusCompletion)completion
{
    [self resetWatermarksWithParams:nil completion:completion];
}
- (void)resetWatermarksWithParams:(MTRSoftwareDiagnosticsClusterResetWatermarksParams * _Nullable)params
                       completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            SoftwareDiagnostics::Commands::ResetWatermarks::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeThreadMetricsWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = SoftwareDiagnostics::Attributes::ThreadMetrics::TypeInfo;
    return MTRReadAttribute<MTRSoftwareDiagnosticsThreadMetricsListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeThreadMetricsWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = SoftwareDiagnostics::Attributes::ThreadMetrics::TypeInfo;
    MTRSubscribeAttribute<MTRSoftwareDiagnosticsThreadMetricsListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeThreadMetricsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRSoftwareDiagnosticsThreadMetricsListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(SoftwareDiagnosticsThreadMetricsListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = SoftwareDiagnostics::Attributes::ThreadMetrics::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCurrentHeapFreeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = SoftwareDiagnostics::Attributes::CurrentHeapFree::TypeInfo;
    return MTRReadAttribute<MTRInt64uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeCurrentHeapFreeWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = SoftwareDiagnostics::Attributes::CurrentHeapFree::TypeInfo;
    MTRSubscribeAttribute<MTRInt64uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeCurrentHeapFreeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt64uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int64uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = SoftwareDiagnostics::Attributes::CurrentHeapFree::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCurrentHeapUsedWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = SoftwareDiagnostics::Attributes::CurrentHeapUsed::TypeInfo;
    return MTRReadAttribute<MTRInt64uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeCurrentHeapUsedWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = SoftwareDiagnostics::Attributes::CurrentHeapUsed::TypeInfo;
    MTRSubscribeAttribute<MTRInt64uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeCurrentHeapUsedWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt64uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int64uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = SoftwareDiagnostics::Attributes::CurrentHeapUsed::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCurrentHeapHighWatermarkWithCompletion:(void (^)(
                                                                NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = SoftwareDiagnostics::Attributes::CurrentHeapHighWatermark::TypeInfo;
    return MTRReadAttribute<MTRInt64uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeCurrentHeapHighWatermarkWithParams:(MTRSubscribeParams * _Nonnull)params
                                     subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = SoftwareDiagnostics::Attributes::CurrentHeapHighWatermark::TypeInfo;
    MTRSubscribeAttribute<MTRInt64uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeCurrentHeapHighWatermarkWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                          endpoint:(NSNumber *)endpoint
                                                             queue:(dispatch_queue_t)queue
                                                        completion:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt64uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int64uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = SoftwareDiagnostics::Attributes::CurrentHeapHighWatermark::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = SoftwareDiagnostics::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRSoftwareDiagnosticsGeneratedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = SoftwareDiagnostics::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRSoftwareDiagnosticsGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRSoftwareDiagnosticsGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(SoftwareDiagnosticsGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = SoftwareDiagnostics::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = SoftwareDiagnostics::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRSoftwareDiagnosticsAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = SoftwareDiagnostics::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRSoftwareDiagnosticsAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRSoftwareDiagnosticsAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(SoftwareDiagnosticsAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = SoftwareDiagnostics::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = SoftwareDiagnostics::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRSoftwareDiagnosticsEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = SoftwareDiagnostics::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRSoftwareDiagnosticsEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRSoftwareDiagnosticsEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(SoftwareDiagnosticsEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = SoftwareDiagnostics::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = SoftwareDiagnostics::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRSoftwareDiagnosticsAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = SoftwareDiagnostics::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRSoftwareDiagnosticsAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRSoftwareDiagnosticsAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(SoftwareDiagnosticsAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = SoftwareDiagnostics::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = SoftwareDiagnostics::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = SoftwareDiagnostics::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = SoftwareDiagnostics::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = SoftwareDiagnostics::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = SoftwareDiagnostics::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = SoftwareDiagnostics::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterSoftwareDiagnostics (Deprecated)

- (void)resetWatermarksWithParams:(MTRSoftwareDiagnosticsClusterResetWatermarksParams * _Nullable)params
                completionHandler:(MTRStatusCompletion)completionHandler
{
    [self resetWatermarksWithParams:params completion:completionHandler];
}
- (void)resetWatermarksWithCompletionHandler:(MTRStatusCompletion)completionHandler
{
    [self resetWatermarksWithParams:nil completionHandler:completionHandler];
}

- (void)readAttributeThreadMetricsWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeThreadMetricsWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeThreadMetricsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeThreadMetricsWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeThreadMetricsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeThreadMetricsWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeCurrentHeapFreeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentHeapFreeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeCurrentHeapFreeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeCurrentHeapFreeWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeCurrentHeapFreeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentHeapFreeWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (void)readAttributeCurrentHeapUsedWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentHeapUsedWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeCurrentHeapUsedWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeCurrentHeapUsedWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeCurrentHeapUsedWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentHeapUsedWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (void)readAttributeCurrentHeapHighWatermarkWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentHeapHighWatermarkWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeCurrentHeapHighWatermarkWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                                           params:(MTRSubscribeParams * _Nullable)params
                                          subscriptionEstablished:
                                              (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                    reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeCurrentHeapHighWatermarkWithParams:subscribeParams
                                       subscriptionEstablished:subscriptionEstablishedHandler
                                                 reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     reportHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}
+ (void)readAttributeCurrentHeapHighWatermarkWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                              completionHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentHeapHighWatermarkWithClusterStateCache:attributeCacheContainer.realContainer
                                                            endpoint:endpoint
                                                               queue:queue
                                                          completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                              // Cast is safe because subclass does not add any selectors.
                                                              completionHandler(static_cast<NSNumber *>(value), error);
                                                          }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterThreadNetworkDiagnostics

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)resetCountsWithCompletion:(MTRStatusCompletion)completion
{
    [self resetCountsWithParams:nil completion:completion];
}
- (void)resetCountsWithParams:(MTRThreadNetworkDiagnosticsClusterResetCountsParams * _Nullable)params
                   completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            ThreadNetworkDiagnostics::Commands::ResetCounts::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeChannelWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::Channel::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeChannelWithParams:(MTRSubscribeParams * _Nonnull)params
                    subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                              reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::Channel::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeChannelWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                       completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::Channel::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRoutingRoleWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::RoutingRole::TypeInfo;
    return MTRReadAttribute<MTRNullableThreadNetworkDiagnosticsClusterRoutingRoleAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRoutingRoleWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::RoutingRole::TypeInfo;
    MTRSubscribeAttribute<MTRNullableThreadNetworkDiagnosticsClusterRoutingRoleAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeRoutingRoleWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableThreadNetworkDiagnosticsClusterRoutingRoleAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(NullableThreadNetworkDiagnosticsClusterRoutingRoleAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::RoutingRole::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNetworkNameWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::NetworkName::TypeInfo;
    return MTRReadAttribute<MTRNullableCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeNetworkNameWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::NetworkName::TypeInfo;
    MTRSubscribeAttribute<MTRNullableCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNetworkNameWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableCharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::NetworkName::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePanIdWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::PanId::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePanIdWithParams:(MTRSubscribeParams * _Nonnull)params
                  subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                            reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::PanId::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePanIdWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                                     completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::PanId::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeExtendedPanIdWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::ExtendedPanId::TypeInfo;
    return MTRReadAttribute<MTRNullableInt64uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeExtendedPanIdWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::ExtendedPanId::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt64uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeExtendedPanIdWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt64uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt64uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::ExtendedPanId::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMeshLocalPrefixWithCompletion:(void (^)(NSData * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::MeshLocalPrefix::TypeInfo;
    return MTRReadAttribute<MTRNullableOctetStringAttributeCallbackBridge, NSData, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMeshLocalPrefixWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSData * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::MeshLocalPrefix::TypeInfo;
    MTRSubscribeAttribute<MTRNullableOctetStringAttributeCallbackSubscriptionBridge, NSData, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMeshLocalPrefixWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:(void (^)(NSData * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableOctetStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableOctetStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::MeshLocalPrefix::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeOverrunCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::OverrunCount::TypeInfo;
    return MTRReadAttribute<MTRInt64uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeOverrunCountWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::OverrunCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt64uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeOverrunCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt64uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int64uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::OverrunCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNeighborTableWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::NeighborTable::TypeInfo;
    return MTRReadAttribute<MTRThreadNetworkDiagnosticsNeighborTableListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeNeighborTableWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::NeighborTable::TypeInfo;
    MTRSubscribeAttribute<MTRThreadNetworkDiagnosticsNeighborTableListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeNeighborTableWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRThreadNetworkDiagnosticsNeighborTableListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ThreadNetworkDiagnosticsNeighborTableListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::NeighborTable::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRouteTableWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::RouteTable::TypeInfo;
    return MTRReadAttribute<MTRThreadNetworkDiagnosticsRouteTableListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRouteTableWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::RouteTable::TypeInfo;
    MTRSubscribeAttribute<MTRThreadNetworkDiagnosticsRouteTableListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeRouteTableWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRThreadNetworkDiagnosticsRouteTableListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ThreadNetworkDiagnosticsRouteTableListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::RouteTable::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePartitionIdWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::PartitionId::TypeInfo;
    return MTRReadAttribute<MTRNullableInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePartitionIdWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::PartitionId::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePartitionIdWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::PartitionId::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeWeightingWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::Weighting::TypeInfo;
    return MTRReadAttribute<MTRNullableInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeWeightingWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::Weighting::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeWeightingWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::Weighting::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeDataVersionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::DataVersion::TypeInfo;
    return MTRReadAttribute<MTRNullableInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeDataVersionWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::DataVersion::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeDataVersionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::DataVersion::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeStableDataVersionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::StableDataVersion::TypeInfo;
    return MTRReadAttribute<MTRNullableInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeStableDataVersionWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::StableDataVersion::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeStableDataVersionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::StableDataVersion::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeLeaderRouterIdWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::LeaderRouterId::TypeInfo;
    return MTRReadAttribute<MTRNullableInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeLeaderRouterIdWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::LeaderRouterId::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeLeaderRouterIdWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::LeaderRouterId::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeDetachedRoleCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::DetachedRoleCount::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeDetachedRoleCountWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::DetachedRoleCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeDetachedRoleCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::DetachedRoleCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeChildRoleCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::ChildRoleCount::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeChildRoleCountWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::ChildRoleCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeChildRoleCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::ChildRoleCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRouterRoleCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::RouterRoleCount::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRouterRoleCountWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::RouterRoleCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRouterRoleCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::RouterRoleCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeLeaderRoleCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::LeaderRoleCount::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeLeaderRoleCountWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::LeaderRoleCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeLeaderRoleCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::LeaderRoleCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttachAttemptCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::AttachAttemptCount::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttachAttemptCountWithParams:(MTRSubscribeParams * _Nonnull)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::AttachAttemptCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttachAttemptCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                                  completion:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::AttachAttemptCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePartitionIdChangeCountWithCompletion:(void (^)(
                                                              NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::PartitionIdChangeCount::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePartitionIdChangeCountWithParams:(MTRSubscribeParams * _Nonnull)params
                                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::PartitionIdChangeCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePartitionIdChangeCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                                      completion:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::PartitionIdChangeCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBetterPartitionAttachAttemptCountWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::BetterPartitionAttachAttemptCount::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeBetterPartitionAttachAttemptCountWithParams:(MTRSubscribeParams * _Nonnull)params
                                              subscriptionEstablished:
                                                  (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                        reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::BetterPartitionAttachAttemptCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeBetterPartitionAttachAttemptCountWithClusterStateCache:
            (MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                                   endpoint:(NSNumber *)endpoint
                                                                      queue:(dispatch_queue_t)queue
                                                                 completion:(void (^)(NSNumber * _Nullable value,
                                                                                NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::BetterPartitionAttachAttemptCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeParentChangeCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::ParentChangeCount::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeParentChangeCountWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::ParentChangeCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeParentChangeCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::ParentChangeCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeTxTotalCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxTotalCount::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeTxTotalCountWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxTotalCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeTxTotalCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxTotalCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeTxUnicastCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxUnicastCount::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeTxUnicastCountWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxUnicastCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeTxUnicastCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxUnicastCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeTxBroadcastCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxBroadcastCount::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeTxBroadcastCountWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxBroadcastCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeTxBroadcastCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxBroadcastCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeTxAckRequestedCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxAckRequestedCount::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeTxAckRequestedCountWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxAckRequestedCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeTxAckRequestedCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxAckRequestedCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeTxAckedCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxAckedCount::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeTxAckedCountWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxAckedCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeTxAckedCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxAckedCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeTxNoAckRequestedCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxNoAckRequestedCount::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeTxNoAckRequestedCountWithParams:(MTRSubscribeParams * _Nonnull)params
                                  subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxNoAckRequestedCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeTxNoAckRequestedCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                                     completion:
                                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxNoAckRequestedCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeTxDataCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxDataCount::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeTxDataCountWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxDataCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeTxDataCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxDataCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeTxDataPollCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxDataPollCount::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeTxDataPollCountWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxDataPollCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeTxDataPollCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxDataPollCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeTxBeaconCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxBeaconCount::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeTxBeaconCountWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxBeaconCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeTxBeaconCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxBeaconCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeTxBeaconRequestCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxBeaconRequestCount::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeTxBeaconRequestCountWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxBeaconRequestCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeTxBeaconRequestCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxBeaconRequestCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeTxOtherCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxOtherCount::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeTxOtherCountWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxOtherCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeTxOtherCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxOtherCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeTxRetryCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxRetryCount::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeTxRetryCountWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxRetryCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeTxRetryCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxRetryCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeTxDirectMaxRetryExpiryCountWithCompletion:(void (^)(
                                                                   NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxDirectMaxRetryExpiryCount::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeTxDirectMaxRetryExpiryCountWithParams:(MTRSubscribeParams * _Nonnull)params
                                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxDirectMaxRetryExpiryCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeTxDirectMaxRetryExpiryCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                             endpoint:(NSNumber *)endpoint
                                                                queue:(dispatch_queue_t)queue
                                                           completion:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxDirectMaxRetryExpiryCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeTxIndirectMaxRetryExpiryCountWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxIndirectMaxRetryExpiryCount::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeTxIndirectMaxRetryExpiryCountWithParams:(MTRSubscribeParams * _Nonnull)params
                                          subscriptionEstablished:
                                              (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                    reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxIndirectMaxRetryExpiryCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeTxIndirectMaxRetryExpiryCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                               endpoint:(NSNumber *)endpoint
                                                                  queue:(dispatch_queue_t)queue
                                                             completion:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxIndirectMaxRetryExpiryCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeTxErrCcaCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxErrCcaCount::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeTxErrCcaCountWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxErrCcaCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeTxErrCcaCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxErrCcaCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeTxErrAbortCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxErrAbortCount::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeTxErrAbortCountWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxErrAbortCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeTxErrAbortCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxErrAbortCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeTxErrBusyChannelCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxErrBusyChannelCount::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeTxErrBusyChannelCountWithParams:(MTRSubscribeParams * _Nonnull)params
                                  subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxErrBusyChannelCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeTxErrBusyChannelCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                                     completion:
                                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxErrBusyChannelCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRxTotalCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxTotalCount::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRxTotalCountWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxTotalCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRxTotalCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxTotalCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRxUnicastCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxUnicastCount::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRxUnicastCountWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxUnicastCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRxUnicastCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxUnicastCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRxBroadcastCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxBroadcastCount::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRxBroadcastCountWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxBroadcastCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRxBroadcastCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxBroadcastCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRxDataCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxDataCount::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRxDataCountWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxDataCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRxDataCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxDataCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRxDataPollCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxDataPollCount::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRxDataPollCountWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxDataPollCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRxDataPollCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxDataPollCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRxBeaconCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxBeaconCount::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRxBeaconCountWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxBeaconCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRxBeaconCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxBeaconCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRxBeaconRequestCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxBeaconRequestCount::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRxBeaconRequestCountWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxBeaconRequestCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRxBeaconRequestCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxBeaconRequestCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRxOtherCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxOtherCount::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRxOtherCountWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxOtherCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRxOtherCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxOtherCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRxAddressFilteredCountWithCompletion:(void (^)(
                                                              NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxAddressFilteredCount::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRxAddressFilteredCountWithParams:(MTRSubscribeParams * _Nonnull)params
                                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxAddressFilteredCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRxAddressFilteredCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                                      completion:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxAddressFilteredCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRxDestAddrFilteredCountWithCompletion:(void (^)(
                                                               NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxDestAddrFilteredCount::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRxDestAddrFilteredCountWithParams:(MTRSubscribeParams * _Nonnull)params
                                    subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxDestAddrFilteredCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRxDestAddrFilteredCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                         endpoint:(NSNumber *)endpoint
                                                            queue:(dispatch_queue_t)queue
                                                       completion:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxDestAddrFilteredCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRxDuplicatedCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxDuplicatedCount::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRxDuplicatedCountWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxDuplicatedCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRxDuplicatedCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxDuplicatedCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRxErrNoFrameCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxErrNoFrameCount::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRxErrNoFrameCountWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxErrNoFrameCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRxErrNoFrameCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxErrNoFrameCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRxErrUnknownNeighborCountWithCompletion:(void (^)(
                                                                 NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxErrUnknownNeighborCount::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRxErrUnknownNeighborCountWithParams:(MTRSubscribeParams * _Nonnull)params
                                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxErrUnknownNeighborCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRxErrUnknownNeighborCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                           endpoint:(NSNumber *)endpoint
                                                              queue:(dispatch_queue_t)queue
                                                         completion:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxErrUnknownNeighborCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRxErrInvalidSrcAddrCountWithCompletion:(void (^)(
                                                                NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxErrInvalidSrcAddrCount::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRxErrInvalidSrcAddrCountWithParams:(MTRSubscribeParams * _Nonnull)params
                                     subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxErrInvalidSrcAddrCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRxErrInvalidSrcAddrCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                          endpoint:(NSNumber *)endpoint
                                                             queue:(dispatch_queue_t)queue
                                                        completion:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxErrInvalidSrcAddrCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRxErrSecCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxErrSecCount::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRxErrSecCountWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxErrSecCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRxErrSecCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxErrSecCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRxErrFcsCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxErrFcsCount::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRxErrFcsCountWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxErrFcsCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRxErrFcsCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxErrFcsCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRxErrOtherCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxErrOtherCount::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRxErrOtherCountWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxErrOtherCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRxErrOtherCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxErrOtherCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeActiveTimestampWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::ActiveTimestamp::TypeInfo;
    return MTRReadAttribute<MTRNullableInt64uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeActiveTimestampWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::ActiveTimestamp::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt64uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeActiveTimestampWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt64uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt64uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::ActiveTimestamp::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePendingTimestampWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::PendingTimestamp::TypeInfo;
    return MTRReadAttribute<MTRNullableInt64uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePendingTimestampWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::PendingTimestamp::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt64uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePendingTimestampWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt64uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt64uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::PendingTimestamp::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeDelayWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::Delay::TypeInfo;
    return MTRReadAttribute<MTRNullableInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeDelayWithParams:(MTRSubscribeParams * _Nonnull)params
                  subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                            reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::Delay::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeDelayWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                                     completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::Delay::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSecurityPolicyWithCompletion:(void (^)(MTRThreadNetworkDiagnosticsClusterSecurityPolicy * _Nullable value,
                                                      NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::SecurityPolicy::TypeInfo;
    return MTRReadAttribute<MTRThreadNetworkDiagnosticsSecurityPolicyStructAttributeCallbackBridge,
        MTRThreadNetworkDiagnosticsClusterSecurityPolicy, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeSecurityPolicyWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(MTRThreadNetworkDiagnosticsClusterSecurityPolicy * _Nullable value,
                                                       NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::SecurityPolicy::TypeInfo;
    MTRSubscribeAttribute<MTRThreadNetworkDiagnosticsSecurityPolicyStructAttributeCallbackSubscriptionBridge,
        MTRThreadNetworkDiagnosticsClusterSecurityPolicy, TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler,
        self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeSecurityPolicyWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:
                                                  (void (^)(MTRThreadNetworkDiagnosticsClusterSecurityPolicy * _Nullable value,
                                                      NSError * _Nullable error))completion
{
    auto * bridge = new MTRThreadNetworkDiagnosticsSecurityPolicyStructAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ThreadNetworkDiagnosticsSecurityPolicyStructAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::SecurityPolicy::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeChannelPage0MaskWithCompletion:(void (^)(NSData * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::ChannelPage0Mask::TypeInfo;
    return MTRReadAttribute<MTRNullableOctetStringAttributeCallbackBridge, NSData, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeChannelPage0MaskWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSData * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::ChannelPage0Mask::TypeInfo;
    MTRSubscribeAttribute<MTRNullableOctetStringAttributeCallbackSubscriptionBridge, NSData, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeChannelPage0MaskWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:(void (^)(NSData * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableOctetStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableOctetStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::ChannelPage0Mask::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeOperationalDatasetComponentsWithCompletion:
    (void (^)(
        MTRThreadNetworkDiagnosticsClusterOperationalDatasetComponents * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::OperationalDatasetComponents::TypeInfo;
    return MTRReadAttribute<MTRThreadNetworkDiagnosticsOperationalDatasetComponentsStructAttributeCallbackBridge,
        MTRThreadNetworkDiagnosticsClusterOperationalDatasetComponents, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)
    subscribeAttributeOperationalDatasetComponentsWithParams:(MTRSubscribeParams * _Nonnull)params
                                     subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                               reportHandler:
                                                   (void (^)(
                                                       MTRThreadNetworkDiagnosticsClusterOperationalDatasetComponents * _Nullable value,
                                                       NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::OperationalDatasetComponents::TypeInfo;
    MTRSubscribeAttribute<MTRThreadNetworkDiagnosticsOperationalDatasetComponentsStructAttributeCallbackSubscriptionBridge,
        MTRThreadNetworkDiagnosticsClusterOperationalDatasetComponents, TypeInfo::DecodableType>(params, subscriptionEstablished,
        reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)
    readAttributeOperationalDatasetComponentsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                          endpoint:(NSNumber *)endpoint
                                                             queue:(dispatch_queue_t)queue
                                                        completion:
                                                            (void (^)(
                                                                MTRThreadNetworkDiagnosticsClusterOperationalDatasetComponents * _Nullable value,
                                                                NSError * _Nullable error))completion
{
    auto * bridge = new MTRThreadNetworkDiagnosticsOperationalDatasetComponentsStructAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ThreadNetworkDiagnosticsOperationalDatasetComponentsStructAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::OperationalDatasetComponents::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeActiveNetworkFaultsListWithCompletion:(void (^)(
                                                               NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::ActiveNetworkFaultsList::TypeInfo;
    return MTRReadAttribute<MTRThreadNetworkDiagnosticsActiveNetworkFaultsListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeActiveNetworkFaultsListWithParams:(MTRSubscribeParams * _Nonnull)params
                                    subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                              reportHandler:
                                                  (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::ActiveNetworkFaultsList::TypeInfo;
    MTRSubscribeAttribute<MTRThreadNetworkDiagnosticsActiveNetworkFaultsListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeActiveNetworkFaultsListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                         endpoint:(NSNumber *)endpoint
                                                            queue:(dispatch_queue_t)queue
                                                       completion:(void (^)(NSArray * _Nullable value,
                                                                      NSError * _Nullable error))completion
{
    auto * bridge = new MTRThreadNetworkDiagnosticsActiveNetworkFaultsListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ThreadNetworkDiagnosticsActiveNetworkFaultsListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::ActiveNetworkFaultsList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRThreadNetworkDiagnosticsGeneratedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRThreadNetworkDiagnosticsGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRThreadNetworkDiagnosticsGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ThreadNetworkDiagnosticsGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRThreadNetworkDiagnosticsAcceptedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRThreadNetworkDiagnosticsAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRThreadNetworkDiagnosticsAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ThreadNetworkDiagnosticsAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRThreadNetworkDiagnosticsEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRThreadNetworkDiagnosticsEventListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRThreadNetworkDiagnosticsEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ThreadNetworkDiagnosticsEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRThreadNetworkDiagnosticsAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRThreadNetworkDiagnosticsAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRThreadNetworkDiagnosticsAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ThreadNetworkDiagnosticsAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThreadNetworkDiagnostics::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterThreadNetworkDiagnostics (Deprecated)

- (void)resetCountsWithParams:(MTRThreadNetworkDiagnosticsClusterResetCountsParams * _Nullable)params
            completionHandler:(MTRStatusCompletion)completionHandler
{
    [self resetCountsWithParams:params completion:completionHandler];
}
- (void)resetCountsWithCompletionHandler:(MTRStatusCompletion)completionHandler
{
    [self resetCountsWithParams:nil completionHandler:completionHandler];
}

- (void)readAttributeChannelWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeChannelWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeChannelWithMinInterval:(NSNumber * _Nonnull)minInterval
                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                          params:(MTRSubscribeParams * _Nullable)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeChannelWithParams:subscribeParams
                      subscriptionEstablished:subscriptionEstablishedHandler
                                reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                    // Cast is safe because subclass does not add any selectors.
                                    reportHandler(static_cast<NSNumber *>(value), error);
                                }];
}
+ (void)readAttributeChannelWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                      endpoint:(NSNumber *)endpoint
                                         queue:(dispatch_queue_t)queue
                             completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeChannelWithClusterStateCache:attributeCacheContainer.realContainer
                                           endpoint:endpoint
                                              queue:queue
                                         completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             completionHandler(static_cast<NSNumber *>(value), error);
                                         }];
}

- (void)readAttributeRoutingRoleWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRoutingRoleWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRoutingRoleWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRoutingRoleWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSNumber *>(value), error);
                                    }];
}
+ (void)readAttributeRoutingRoleWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRoutingRoleWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                             }];
}

- (void)readAttributeNetworkNameWithCompletionHandler:(void (^)(
                                                          NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNetworkNameWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)subscribeAttributeNetworkNameWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNetworkNameWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSString *>(value), error);
                                    }];
}
+ (void)readAttributeNetworkNameWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNetworkNameWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSString *>(value), error);
                                             }];
}

- (void)readAttributePanIdWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePanIdWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributePanIdWithMinInterval:(NSNumber * _Nonnull)minInterval
                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                        params:(MTRSubscribeParams * _Nullable)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePanIdWithParams:subscribeParams
                    subscriptionEstablished:subscriptionEstablishedHandler
                              reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                  // Cast is safe because subclass does not add any selectors.
                                  reportHandler(static_cast<NSNumber *>(value), error);
                              }];
}
+ (void)readAttributePanIdWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                    endpoint:(NSNumber *)endpoint
                                       queue:(dispatch_queue_t)queue
                           completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePanIdWithClusterStateCache:attributeCacheContainer.realContainer
                                         endpoint:endpoint
                                            queue:queue
                                       completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           completionHandler(static_cast<NSNumber *>(value), error);
                                       }];
}

- (void)readAttributeExtendedPanIdWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeExtendedPanIdWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeExtendedPanIdWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeExtendedPanIdWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributeExtendedPanIdWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeExtendedPanIdWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributeMeshLocalPrefixWithCompletionHandler:(void (^)(
                                                              NSData * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMeshLocalPrefixWithCompletion:^(NSData * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSData *>(value), error);
    }];
}
- (void)subscribeAttributeMeshLocalPrefixWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSData * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMeshLocalPrefixWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSData * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSData *>(value), error);
                                        }];
}
+ (void)readAttributeMeshLocalPrefixWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSData * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMeshLocalPrefixWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSData * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSData *>(value), error);
                                                 }];
}

- (void)readAttributeOverrunCountWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOverrunCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeOverrunCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeOverrunCountWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributeOverrunCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOverrunCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributeNeighborTableListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeNeighborTableWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)
    subscribeAttributeNeighborTableListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNeighborTableWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeNeighborTableListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNeighborTableWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeRouteTableListWithCompletionHandler:(void (^)(
                                                             NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRouteTableWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeRouteTableListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRouteTableWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSArray *>(value), error);
                                   }];
}
+ (void)readAttributeRouteTableListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRouteTableWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSArray *>(value), error);
                                            }];
}

- (void)readAttributePartitionIdWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePartitionIdWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributePartitionIdWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePartitionIdWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSNumber *>(value), error);
                                    }];
}
+ (void)readAttributePartitionIdWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePartitionIdWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                             }];
}

- (void)readAttributeWeightingWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeWeightingWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeWeightingWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeWeightingWithParams:subscribeParams
                        subscriptionEstablished:subscriptionEstablishedHandler
                                  reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                      // Cast is safe because subclass does not add any selectors.
                                      reportHandler(static_cast<NSNumber *>(value), error);
                                  }];
}
+ (void)readAttributeWeightingWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeWeightingWithClusterStateCache:attributeCacheContainer.realContainer
                                             endpoint:endpoint
                                                queue:queue
                                           completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               completionHandler(static_cast<NSNumber *>(value), error);
                                           }];
}

- (void)readAttributeDataVersionWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDataVersionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeDataVersionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeDataVersionWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSNumber *>(value), error);
                                    }];
}
+ (void)readAttributeDataVersionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDataVersionWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                             }];
}

- (void)readAttributeStableDataVersionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeStableDataVersionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeStableDataVersionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeStableDataVersionWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSNumber *>(value), error);
                                          }];
}
+ (void)readAttributeStableDataVersionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeStableDataVersionWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}

- (void)readAttributeLeaderRouterIdWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeLeaderRouterIdWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeLeaderRouterIdWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeLeaderRouterIdWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSNumber *>(value), error);
                                       }];
}
+ (void)readAttributeLeaderRouterIdWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLeaderRouterIdWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSNumber *>(value), error);
                                                }];
}

- (void)readAttributeDetachedRoleCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeDetachedRoleCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeDetachedRoleCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeDetachedRoleCountWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSNumber *>(value), error);
                                          }];
}
+ (void)readAttributeDetachedRoleCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDetachedRoleCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}

- (void)readAttributeChildRoleCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeChildRoleCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeChildRoleCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeChildRoleCountWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSNumber *>(value), error);
                                       }];
}
+ (void)readAttributeChildRoleCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeChildRoleCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSNumber *>(value), error);
                                                }];
}

- (void)readAttributeRouterRoleCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeRouterRoleCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRouterRoleCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRouterRoleCountWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeRouterRoleCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRouterRoleCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (void)readAttributeLeaderRoleCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeLeaderRoleCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeLeaderRoleCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeLeaderRoleCountWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeLeaderRoleCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLeaderRoleCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (void)readAttributeAttachAttemptCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    [self readAttributeAttachAttemptCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeAttachAttemptCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:
                                        (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttachAttemptCountWithParams:subscribeParams
                                 subscriptionEstablished:subscriptionEstablishedHandler
                                           reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               reportHandler(static_cast<NSNumber *>(value), error);
                                           }];
}
+ (void)readAttributeAttachAttemptCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttachAttemptCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                      endpoint:endpoint
                                                         queue:queue
                                                    completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                        // Cast is safe because subclass does not add any selectors.
                                                        completionHandler(static_cast<NSNumber *>(value), error);
                                                    }];
}

- (void)readAttributePartitionIdChangeCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    [self readAttributePartitionIdChangeCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributePartitionIdChangeCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                                         params:(MTRSubscribeParams * _Nullable)params
                                        subscriptionEstablished:
                                            (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePartitionIdChangeCountWithParams:subscribeParams
                                     subscriptionEstablished:subscriptionEstablishedHandler
                                               reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   reportHandler(static_cast<NSNumber *>(value), error);
                                               }];
}
+ (void)readAttributePartitionIdChangeCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                            completionHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePartitionIdChangeCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                          endpoint:endpoint
                                                             queue:queue
                                                        completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                            // Cast is safe because subclass does not add any selectors.
                                                            completionHandler(static_cast<NSNumber *>(value), error);
                                                        }];
}

- (void)readAttributeBetterPartitionAttachAttemptCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeBetterPartitionAttachAttemptCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeBetterPartitionAttachAttemptCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                    params:(MTRSubscribeParams * _Nullable)params
                                                   subscriptionEstablished:
                                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                             reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                               NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeBetterPartitionAttachAttemptCountWithParams:subscribeParams
                                                subscriptionEstablished:subscriptionEstablishedHandler
                                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                              // Cast is safe because subclass does not add any selectors.
                                                              reportHandler(static_cast<NSNumber *>(value), error);
                                                          }];
}
+ (void)readAttributeBetterPartitionAttachAttemptCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                                endpoint:(NSNumber *)endpoint
                                                                   queue:(dispatch_queue_t)queue
                                                       completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeBetterPartitionAttachAttemptCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                                     endpoint:endpoint
                                                                        queue:queue
                                                                   completion:^(
                                                                       NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                       // Cast is safe because subclass does not add any selectors.
                                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                                   }];
}

- (void)readAttributeParentChangeCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeParentChangeCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeParentChangeCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeParentChangeCountWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSNumber *>(value), error);
                                          }];
}
+ (void)readAttributeParentChangeCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeParentChangeCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}

- (void)readAttributeTxTotalCountWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeTxTotalCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeTxTotalCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeTxTotalCountWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributeTxTotalCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeTxTotalCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributeTxUnicastCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeTxUnicastCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeTxUnicastCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeTxUnicastCountWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSNumber *>(value), error);
                                       }];
}
+ (void)readAttributeTxUnicastCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeTxUnicastCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSNumber *>(value), error);
                                                }];
}

- (void)readAttributeTxBroadcastCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeTxBroadcastCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)
    subscribeAttributeTxBroadcastCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeTxBroadcastCountWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributeTxBroadcastCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeTxBroadcastCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeTxAckRequestedCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeTxAckRequestedCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeTxAckRequestedCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeTxAckRequestedCountWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSNumber *>(value), error);
                                            }];
}
+ (void)readAttributeTxAckRequestedCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeTxAckRequestedCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}

- (void)readAttributeTxAckedCountWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeTxAckedCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeTxAckedCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeTxAckedCountWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributeTxAckedCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeTxAckedCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributeTxNoAckRequestedCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    [self readAttributeTxNoAckRequestedCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeTxNoAckRequestedCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeTxNoAckRequestedCountWithParams:subscribeParams
                                    subscriptionEstablished:subscriptionEstablishedHandler
                                              reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  reportHandler(static_cast<NSNumber *>(value), error);
                                              }];
}
+ (void)readAttributeTxNoAckRequestedCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeTxNoAckRequestedCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                         endpoint:endpoint
                                                            queue:queue
                                                       completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                           // Cast is safe because subclass does not add any selectors.
                                                           completionHandler(static_cast<NSNumber *>(value), error);
                                                       }];
}

- (void)readAttributeTxDataCountWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeTxDataCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeTxDataCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeTxDataCountWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSNumber *>(value), error);
                                    }];
}
+ (void)readAttributeTxDataCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeTxDataCountWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                             }];
}

- (void)readAttributeTxDataPollCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeTxDataPollCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeTxDataPollCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeTxDataPollCountWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeTxDataPollCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeTxDataPollCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (void)readAttributeTxBeaconCountWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeTxBeaconCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeTxBeaconCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeTxBeaconCountWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributeTxBeaconCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeTxBeaconCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributeTxBeaconRequestCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeTxBeaconRequestCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeTxBeaconRequestCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeTxBeaconRequestCountWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSNumber *>(value), error);
                                             }];
}
+ (void)readAttributeTxBeaconRequestCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeTxBeaconRequestCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSNumber *>(value), error);
                                                      }];
}

- (void)readAttributeTxOtherCountWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeTxOtherCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeTxOtherCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeTxOtherCountWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributeTxOtherCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeTxOtherCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributeTxRetryCountWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeTxRetryCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeTxRetryCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeTxRetryCountWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributeTxRetryCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeTxRetryCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributeTxDirectMaxRetryExpiryCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))completionHandler
{
    [self readAttributeTxDirectMaxRetryExpiryCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeTxDirectMaxRetryExpiryCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                                              params:(MTRSubscribeParams * _Nullable)params
                                             subscriptionEstablished:
                                                 (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                       reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeTxDirectMaxRetryExpiryCountWithParams:subscribeParams
                                          subscriptionEstablished:subscriptionEstablishedHandler
                                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                        // Cast is safe because subclass does not add any selectors.
                                                        reportHandler(static_cast<NSNumber *>(value), error);
                                                    }];
}
+ (void)readAttributeTxDirectMaxRetryExpiryCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                          endpoint:(NSNumber *)endpoint
                                                             queue:(dispatch_queue_t)queue
                                                 completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completionHandler
{
    [self readAttributeTxDirectMaxRetryExpiryCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                               endpoint:endpoint
                                                                  queue:queue
                                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                 // Cast is safe because subclass does not add any selectors.
                                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                                             }];
}

- (void)readAttributeTxIndirectMaxRetryExpiryCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))completionHandler
{
    [self readAttributeTxIndirectMaxRetryExpiryCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeTxIndirectMaxRetryExpiryCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                params:(MTRSubscribeParams * _Nullable)params
                                               subscriptionEstablished:
                                                   (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                         reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeTxIndirectMaxRetryExpiryCountWithParams:subscribeParams
                                            subscriptionEstablished:subscriptionEstablishedHandler
                                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          reportHandler(static_cast<NSNumber *>(value), error);
                                                      }];
}
+ (void)readAttributeTxIndirectMaxRetryExpiryCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                            endpoint:(NSNumber *)endpoint
                                                               queue:(dispatch_queue_t)queue
                                                   completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    [self readAttributeTxIndirectMaxRetryExpiryCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                                 endpoint:endpoint
                                                                    queue:queue
                                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                   // Cast is safe because subclass does not add any selectors.
                                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                                               }];
}

- (void)readAttributeTxErrCcaCountWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeTxErrCcaCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeTxErrCcaCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeTxErrCcaCountWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributeTxErrCcaCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeTxErrCcaCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributeTxErrAbortCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeTxErrAbortCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeTxErrAbortCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeTxErrAbortCountWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeTxErrAbortCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeTxErrAbortCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (void)readAttributeTxErrBusyChannelCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    [self readAttributeTxErrBusyChannelCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeTxErrBusyChannelCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeTxErrBusyChannelCountWithParams:subscribeParams
                                    subscriptionEstablished:subscriptionEstablishedHandler
                                              reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  reportHandler(static_cast<NSNumber *>(value), error);
                                              }];
}
+ (void)readAttributeTxErrBusyChannelCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeTxErrBusyChannelCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                         endpoint:endpoint
                                                            queue:queue
                                                       completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                           // Cast is safe because subclass does not add any selectors.
                                                           completionHandler(static_cast<NSNumber *>(value), error);
                                                       }];
}

- (void)readAttributeRxTotalCountWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRxTotalCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRxTotalCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRxTotalCountWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributeRxTotalCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRxTotalCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributeRxUnicastCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeRxUnicastCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRxUnicastCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRxUnicastCountWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSNumber *>(value), error);
                                       }];
}
+ (void)readAttributeRxUnicastCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRxUnicastCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSNumber *>(value), error);
                                                }];
}

- (void)readAttributeRxBroadcastCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeRxBroadcastCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)
    subscribeAttributeRxBroadcastCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRxBroadcastCountWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributeRxBroadcastCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRxBroadcastCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeRxDataCountWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRxDataCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRxDataCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRxDataCountWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSNumber *>(value), error);
                                    }];
}
+ (void)readAttributeRxDataCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRxDataCountWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                             }];
}

- (void)readAttributeRxDataPollCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeRxDataPollCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRxDataPollCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRxDataPollCountWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeRxDataPollCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRxDataPollCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (void)readAttributeRxBeaconCountWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRxBeaconCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRxBeaconCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRxBeaconCountWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributeRxBeaconCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRxBeaconCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributeRxBeaconRequestCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeRxBeaconRequestCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRxBeaconRequestCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRxBeaconRequestCountWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSNumber *>(value), error);
                                             }];
}
+ (void)readAttributeRxBeaconRequestCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRxBeaconRequestCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSNumber *>(value), error);
                                                      }];
}

- (void)readAttributeRxOtherCountWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRxOtherCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRxOtherCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRxOtherCountWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributeRxOtherCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRxOtherCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributeRxAddressFilteredCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    [self readAttributeRxAddressFilteredCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRxAddressFilteredCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                                         params:(MTRSubscribeParams * _Nullable)params
                                        subscriptionEstablished:
                                            (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRxAddressFilteredCountWithParams:subscribeParams
                                     subscriptionEstablished:subscriptionEstablishedHandler
                                               reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   reportHandler(static_cast<NSNumber *>(value), error);
                                               }];
}
+ (void)readAttributeRxAddressFilteredCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                            completionHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRxAddressFilteredCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                          endpoint:endpoint
                                                             queue:queue
                                                        completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                            // Cast is safe because subclass does not add any selectors.
                                                            completionHandler(static_cast<NSNumber *>(value), error);
                                                        }];
}

- (void)readAttributeRxDestAddrFilteredCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    [self readAttributeRxDestAddrFilteredCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRxDestAddrFilteredCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                                          params:(MTRSubscribeParams * _Nullable)params
                                         subscriptionEstablished:
                                             (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                   reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRxDestAddrFilteredCountWithParams:subscribeParams
                                      subscriptionEstablished:subscriptionEstablishedHandler
                                                reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    reportHandler(static_cast<NSNumber *>(value), error);
                                                }];
}
+ (void)readAttributeRxDestAddrFilteredCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                             completionHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRxDestAddrFilteredCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                           endpoint:endpoint
                                                              queue:queue
                                                         completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                             // Cast is safe because subclass does not add any selectors.
                                                             completionHandler(static_cast<NSNumber *>(value), error);
                                                         }];
}

- (void)readAttributeRxDuplicatedCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeRxDuplicatedCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRxDuplicatedCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRxDuplicatedCountWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSNumber *>(value), error);
                                          }];
}
+ (void)readAttributeRxDuplicatedCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRxDuplicatedCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}

- (void)readAttributeRxErrNoFrameCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeRxErrNoFrameCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRxErrNoFrameCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRxErrNoFrameCountWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSNumber *>(value), error);
                                          }];
}
+ (void)readAttributeRxErrNoFrameCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRxErrNoFrameCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}

- (void)readAttributeRxErrUnknownNeighborCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    [self readAttributeRxErrUnknownNeighborCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRxErrUnknownNeighborCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                                            params:(MTRSubscribeParams * _Nullable)params
                                           subscriptionEstablished:
                                               (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                     reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRxErrUnknownNeighborCountWithParams:subscribeParams
                                        subscriptionEstablished:subscriptionEstablishedHandler
                                                  reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      reportHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}
+ (void)readAttributeRxErrUnknownNeighborCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                               completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    [self readAttributeRxErrUnknownNeighborCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                             endpoint:endpoint
                                                                queue:queue
                                                           completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                               // Cast is safe because subclass does not add any selectors.
                                                               completionHandler(static_cast<NSNumber *>(value), error);
                                                           }];
}

- (void)readAttributeRxErrInvalidSrcAddrCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completionHandler
{
    [self readAttributeRxErrInvalidSrcAddrCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRxErrInvalidSrcAddrCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                                           params:(MTRSubscribeParams * _Nullable)params
                                          subscriptionEstablished:
                                              (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                    reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRxErrInvalidSrcAddrCountWithParams:subscribeParams
                                       subscriptionEstablished:subscriptionEstablishedHandler
                                                 reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     reportHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}
+ (void)readAttributeRxErrInvalidSrcAddrCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                              completionHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRxErrInvalidSrcAddrCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                            endpoint:endpoint
                                                               queue:queue
                                                          completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                              // Cast is safe because subclass does not add any selectors.
                                                              completionHandler(static_cast<NSNumber *>(value), error);
                                                          }];
}

- (void)readAttributeRxErrSecCountWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRxErrSecCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRxErrSecCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRxErrSecCountWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributeRxErrSecCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRxErrSecCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributeRxErrFcsCountWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRxErrFcsCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRxErrFcsCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRxErrFcsCountWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributeRxErrFcsCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRxErrFcsCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributeRxErrOtherCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeRxErrOtherCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRxErrOtherCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRxErrOtherCountWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeRxErrOtherCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRxErrOtherCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (void)readAttributeActiveTimestampWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeActiveTimestampWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeActiveTimestampWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeActiveTimestampWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeActiveTimestampWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeActiveTimestampWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (void)readAttributePendingTimestampWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributePendingTimestampWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)
    subscribeAttributePendingTimestampWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePendingTimestampWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributePendingTimestampWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePendingTimestampWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeDelayWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDelayWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeDelayWithMinInterval:(NSNumber * _Nonnull)minInterval
                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                        params:(MTRSubscribeParams * _Nullable)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeDelayWithParams:subscribeParams
                    subscriptionEstablished:subscriptionEstablishedHandler
                              reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                  // Cast is safe because subclass does not add any selectors.
                                  reportHandler(static_cast<NSNumber *>(value), error);
                              }];
}
+ (void)readAttributeDelayWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                    endpoint:(NSNumber *)endpoint
                                       queue:(dispatch_queue_t)queue
                           completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDelayWithClusterStateCache:attributeCacheContainer.realContainer
                                         endpoint:endpoint
                                            queue:queue
                                       completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           completionHandler(static_cast<NSNumber *>(value), error);
                                       }];
}

- (void)readAttributeSecurityPolicyWithCompletionHandler:
    (void (^)(MTRThreadNetworkDiagnosticsClusterSecurityPolicy * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSecurityPolicyWithCompletion:^(
        MTRThreadNetworkDiagnosticsClusterSecurityPolicy * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<MTRThreadNetworkDiagnosticsClusterSecurityPolicy *>(value), error);
    }];
}
- (void)subscribeAttributeSecurityPolicyWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(MTRThreadNetworkDiagnosticsClusterSecurityPolicy * _Nullable value,
                                                  NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeSecurityPolicyWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(MTRThreadNetworkDiagnosticsClusterSecurityPolicy * _Nullable value,
                                           NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(
                                               static_cast<MTRThreadNetworkDiagnosticsClusterSecurityPolicy *>(value), error);
                                       }];
}
+ (void)readAttributeSecurityPolicyWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:(void (^)(MTRThreadNetworkDiagnosticsClusterSecurityPolicy * _Nullable value,
                                                          NSError * _Nullable error))completionHandler
{
    [self readAttributeSecurityPolicyWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(MTRThreadNetworkDiagnosticsClusterSecurityPolicy * _Nullable value,
                                                    NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(
                                                        static_cast<MTRThreadNetworkDiagnosticsClusterSecurityPolicy *>(value),
                                                        error);
                                                }];
}

- (void)readAttributeChannelPage0MaskWithCompletionHandler:(void (^)(NSData * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeChannelPage0MaskWithCompletion:^(NSData * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSData *>(value), error);
    }];
}
- (void)
    subscribeAttributeChannelPage0MaskWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSData * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeChannelPage0MaskWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSData * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSData *>(value), error);
                                         }];
}
+ (void)readAttributeChannelPage0MaskWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSData * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeChannelPage0MaskWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSData * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSData *>(value), error);
                                                  }];
}

- (void)readAttributeOperationalDatasetComponentsWithCompletionHandler:
    (void (^)(MTRThreadNetworkDiagnosticsClusterOperationalDatasetComponents * _Nullable value,
        NSError * _Nullable error))completionHandler
{
    [self readAttributeOperationalDatasetComponentsWithCompletion:^(
        MTRThreadNetworkDiagnosticsClusterOperationalDatasetComponents * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<MTRThreadNetworkDiagnosticsClusterOperationalDatasetComponents *>(value), error);
    }];
}
- (void)
    subscribeAttributeOperationalDatasetComponentsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                                           params:(MTRSubscribeParams * _Nullable)params
                                          subscriptionEstablished:
                                              (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                    reportHandler:
                                                        (void (^)(
                                                            MTRThreadNetworkDiagnosticsClusterOperationalDatasetComponents * _Nullable value,
                                                            NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self
        subscribeAttributeOperationalDatasetComponentsWithParams:subscribeParams
                                         subscriptionEstablished:subscriptionEstablishedHandler
                                                   reportHandler:^(
                                                       MTRThreadNetworkDiagnosticsClusterOperationalDatasetComponents * _Nullable value,
                                                       NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       reportHandler(
                                                           static_cast<
                                                               MTRThreadNetworkDiagnosticsClusterOperationalDatasetComponents *>(
                                                               value),
                                                           error);
                                                   }];
}
+ (void)
    readAttributeOperationalDatasetComponentsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                              completionHandler:
                                                  (void (^)(
                                                      MTRThreadNetworkDiagnosticsClusterOperationalDatasetComponents * _Nullable value,
                                                      NSError * _Nullable error))completionHandler
{
    [self
        readAttributeOperationalDatasetComponentsWithClusterStateCache:attributeCacheContainer.realContainer
                                                              endpoint:endpoint
                                                                 queue:queue
                                                            completion:^(
                                                                MTRThreadNetworkDiagnosticsClusterOperationalDatasetComponents * _Nullable value,
                                                                NSError * _Nullable error) {
                                                                // Cast is safe because subclass does not add any selectors.
                                                                completionHandler(
                                                                    static_cast<
                                                                        MTRThreadNetworkDiagnosticsClusterOperationalDatasetComponents *>(
                                                                        value),
                                                                    error);
                                                            }];
}

- (void)readAttributeActiveNetworkFaultsListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    [self readAttributeActiveNetworkFaultsListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeActiveNetworkFaultsListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                                          params:(MTRSubscribeParams * _Nullable)params
                                         subscriptionEstablished:
                                             (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                   reportHandler:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeActiveNetworkFaultsListWithParams:subscribeParams
                                      subscriptionEstablished:subscriptionEstablishedHandler
                                                reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    reportHandler(static_cast<NSArray *>(value), error);
                                                }];
}
+ (void)readAttributeActiveNetworkFaultsListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                             completionHandler:
                                                 (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeActiveNetworkFaultsListWithClusterStateCache:attributeCacheContainer.realContainer
                                                           endpoint:endpoint
                                                              queue:queue
                                                         completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                             // Cast is safe because subclass does not add any selectors.
                                                             completionHandler(static_cast<NSArray *>(value), error);
                                                         }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterWiFiNetworkDiagnostics

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)resetCountsWithCompletion:(MTRStatusCompletion)completion
{
    [self resetCountsWithParams:nil completion:completion];
}
- (void)resetCountsWithParams:(MTRWiFiNetworkDiagnosticsClusterResetCountsParams * _Nullable)params
                   completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            WiFiNetworkDiagnostics::Commands::ResetCounts::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeBSSIDWithCompletion:(void (^)(NSData * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WiFiNetworkDiagnostics::Attributes::Bssid::TypeInfo;
    return MTRReadAttribute<MTRNullableOctetStringAttributeCallbackBridge, NSData, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeBSSIDWithParams:(MTRSubscribeParams * _Nonnull)params
                  subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                            reportHandler:(void (^)(NSData * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WiFiNetworkDiagnostics::Attributes::Bssid::TypeInfo;
    MTRSubscribeAttribute<MTRNullableOctetStringAttributeCallbackSubscriptionBridge, NSData, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeBSSIDWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                                     completion:(void (^)(NSData * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableOctetStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableOctetStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WiFiNetworkDiagnostics::Attributes::Bssid::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSecurityTypeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WiFiNetworkDiagnostics::Attributes::SecurityType::TypeInfo;
    return MTRReadAttribute<MTRNullableWiFiNetworkDiagnosticsClusterSecurityTypeEnumAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeSecurityTypeWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WiFiNetworkDiagnostics::Attributes::SecurityType::TypeInfo;
    MTRSubscribeAttribute<MTRNullableWiFiNetworkDiagnosticsClusterSecurityTypeEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeSecurityTypeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableWiFiNetworkDiagnosticsClusterSecurityTypeEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(NullableWiFiNetworkDiagnosticsClusterSecurityTypeEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WiFiNetworkDiagnostics::Attributes::SecurityType::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeWiFiVersionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WiFiNetworkDiagnostics::Attributes::WiFiVersion::TypeInfo;
    return MTRReadAttribute<MTRNullableWiFiNetworkDiagnosticsClusterWiFiVersionEnumAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeWiFiVersionWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WiFiNetworkDiagnostics::Attributes::WiFiVersion::TypeInfo;
    MTRSubscribeAttribute<MTRNullableWiFiNetworkDiagnosticsClusterWiFiVersionEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeWiFiVersionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableWiFiNetworkDiagnosticsClusterWiFiVersionEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(NullableWiFiNetworkDiagnosticsClusterWiFiVersionEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WiFiNetworkDiagnostics::Attributes::WiFiVersion::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeChannelNumberWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WiFiNetworkDiagnostics::Attributes::ChannelNumber::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeChannelNumberWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WiFiNetworkDiagnostics::Attributes::ChannelNumber::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeChannelNumberWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WiFiNetworkDiagnostics::Attributes::ChannelNumber::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRSSIWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WiFiNetworkDiagnostics::Attributes::Rssi::TypeInfo;
    return MTRReadAttribute<MTRNullableInt8sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRSSIWithParams:(MTRSubscribeParams * _Nonnull)params
                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                           reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WiFiNetworkDiagnostics::Attributes::Rssi::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt8sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRSSIWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                      endpoint:(NSNumber *)endpoint
                                         queue:(dispatch_queue_t)queue
                                    completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt8sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt8sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WiFiNetworkDiagnostics::Attributes::Rssi::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBeaconLostCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WiFiNetworkDiagnostics::Attributes::BeaconLostCount::TypeInfo;
    return MTRReadAttribute<MTRNullableInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeBeaconLostCountWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WiFiNetworkDiagnostics::Attributes::BeaconLostCount::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeBeaconLostCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WiFiNetworkDiagnostics::Attributes::BeaconLostCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBeaconRxCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WiFiNetworkDiagnostics::Attributes::BeaconRxCount::TypeInfo;
    return MTRReadAttribute<MTRNullableInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeBeaconRxCountWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WiFiNetworkDiagnostics::Attributes::BeaconRxCount::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeBeaconRxCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WiFiNetworkDiagnostics::Attributes::BeaconRxCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePacketMulticastRxCountWithCompletion:(void (^)(
                                                              NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WiFiNetworkDiagnostics::Attributes::PacketMulticastRxCount::TypeInfo;
    return MTRReadAttribute<MTRNullableInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePacketMulticastRxCountWithParams:(MTRSubscribeParams * _Nonnull)params
                                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WiFiNetworkDiagnostics::Attributes::PacketMulticastRxCount::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePacketMulticastRxCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                                      completion:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WiFiNetworkDiagnostics::Attributes::PacketMulticastRxCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePacketMulticastTxCountWithCompletion:(void (^)(
                                                              NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WiFiNetworkDiagnostics::Attributes::PacketMulticastTxCount::TypeInfo;
    return MTRReadAttribute<MTRNullableInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePacketMulticastTxCountWithParams:(MTRSubscribeParams * _Nonnull)params
                                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WiFiNetworkDiagnostics::Attributes::PacketMulticastTxCount::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePacketMulticastTxCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                                      completion:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WiFiNetworkDiagnostics::Attributes::PacketMulticastTxCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePacketUnicastRxCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WiFiNetworkDiagnostics::Attributes::PacketUnicastRxCount::TypeInfo;
    return MTRReadAttribute<MTRNullableInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePacketUnicastRxCountWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WiFiNetworkDiagnostics::Attributes::PacketUnicastRxCount::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePacketUnicastRxCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WiFiNetworkDiagnostics::Attributes::PacketUnicastRxCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePacketUnicastTxCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WiFiNetworkDiagnostics::Attributes::PacketUnicastTxCount::TypeInfo;
    return MTRReadAttribute<MTRNullableInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePacketUnicastTxCountWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WiFiNetworkDiagnostics::Attributes::PacketUnicastTxCount::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePacketUnicastTxCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WiFiNetworkDiagnostics::Attributes::PacketUnicastTxCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCurrentMaxRateWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WiFiNetworkDiagnostics::Attributes::CurrentMaxRate::TypeInfo;
    return MTRReadAttribute<MTRNullableInt64uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeCurrentMaxRateWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WiFiNetworkDiagnostics::Attributes::CurrentMaxRate::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt64uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeCurrentMaxRateWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt64uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt64uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WiFiNetworkDiagnostics::Attributes::CurrentMaxRate::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeOverrunCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WiFiNetworkDiagnostics::Attributes::OverrunCount::TypeInfo;
    return MTRReadAttribute<MTRNullableInt64uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeOverrunCountWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WiFiNetworkDiagnostics::Attributes::OverrunCount::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt64uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeOverrunCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt64uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt64uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WiFiNetworkDiagnostics::Attributes::OverrunCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WiFiNetworkDiagnostics::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRWiFiNetworkDiagnosticsGeneratedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WiFiNetworkDiagnostics::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRWiFiNetworkDiagnosticsGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRWiFiNetworkDiagnosticsGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(WiFiNetworkDiagnosticsGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WiFiNetworkDiagnostics::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WiFiNetworkDiagnostics::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRWiFiNetworkDiagnosticsAcceptedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WiFiNetworkDiagnostics::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRWiFiNetworkDiagnosticsAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRWiFiNetworkDiagnosticsAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(WiFiNetworkDiagnosticsAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WiFiNetworkDiagnostics::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WiFiNetworkDiagnostics::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRWiFiNetworkDiagnosticsEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WiFiNetworkDiagnostics::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRWiFiNetworkDiagnosticsEventListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRWiFiNetworkDiagnosticsEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(WiFiNetworkDiagnosticsEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WiFiNetworkDiagnostics::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WiFiNetworkDiagnostics::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRWiFiNetworkDiagnosticsAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WiFiNetworkDiagnostics::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRWiFiNetworkDiagnosticsAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRWiFiNetworkDiagnosticsAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(WiFiNetworkDiagnosticsAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WiFiNetworkDiagnostics::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WiFiNetworkDiagnostics::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WiFiNetworkDiagnostics::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WiFiNetworkDiagnostics::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WiFiNetworkDiagnostics::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WiFiNetworkDiagnostics::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WiFiNetworkDiagnostics::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterWiFiNetworkDiagnostics (Deprecated)

- (void)resetCountsWithParams:(MTRWiFiNetworkDiagnosticsClusterResetCountsParams * _Nullable)params
            completionHandler:(MTRStatusCompletion)completionHandler
{
    [self resetCountsWithParams:params completion:completionHandler];
}
- (void)resetCountsWithCompletionHandler:(MTRStatusCompletion)completionHandler
{
    [self resetCountsWithParams:nil completionHandler:completionHandler];
}

- (void)readAttributeBssidWithCompletionHandler:(void (^)(NSData * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBSSIDWithCompletion:^(NSData * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSData *>(value), error);
    }];
}
- (void)subscribeAttributeBssidWithMinInterval:(NSNumber * _Nonnull)minInterval
                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                        params:(MTRSubscribeParams * _Nullable)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                 reportHandler:(void (^)(NSData * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeBSSIDWithParams:subscribeParams
                    subscriptionEstablished:subscriptionEstablishedHandler
                              reportHandler:^(NSData * _Nullable value, NSError * _Nullable error) {
                                  // Cast is safe because subclass does not add any selectors.
                                  reportHandler(static_cast<NSData *>(value), error);
                              }];
}
+ (void)readAttributeBssidWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                    endpoint:(NSNumber *)endpoint
                                       queue:(dispatch_queue_t)queue
                           completionHandler:(void (^)(NSData * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBSSIDWithClusterStateCache:attributeCacheContainer.realContainer
                                         endpoint:endpoint
                                            queue:queue
                                       completion:^(NSData * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           completionHandler(static_cast<NSData *>(value), error);
                                       }];
}

- (void)readAttributeSecurityTypeWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSecurityTypeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeSecurityTypeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeSecurityTypeWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributeSecurityTypeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSecurityTypeWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributeWiFiVersionWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeWiFiVersionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeWiFiVersionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeWiFiVersionWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSNumber *>(value), error);
                                    }];
}
+ (void)readAttributeWiFiVersionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeWiFiVersionWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                             }];
}

- (void)readAttributeChannelNumberWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeChannelNumberWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeChannelNumberWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeChannelNumberWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributeChannelNumberWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeChannelNumberWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributeRssiWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRSSIWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRssiWithMinInterval:(NSNumber * _Nonnull)minInterval
                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                       params:(MTRSubscribeParams * _Nullable)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRSSIWithParams:subscribeParams
                   subscriptionEstablished:subscriptionEstablishedHandler
                             reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                 // Cast is safe because subclass does not add any selectors.
                                 reportHandler(static_cast<NSNumber *>(value), error);
                             }];
}
+ (void)readAttributeRssiWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                   endpoint:(NSNumber *)endpoint
                                      queue:(dispatch_queue_t)queue
                          completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRSSIWithClusterStateCache:attributeCacheContainer.realContainer
                                        endpoint:endpoint
                                           queue:queue
                                      completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          completionHandler(static_cast<NSNumber *>(value), error);
                                      }];
}

- (void)readAttributeBeaconLostCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeBeaconLostCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeBeaconLostCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeBeaconLostCountWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeBeaconLostCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBeaconLostCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (void)readAttributeBeaconRxCountWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBeaconRxCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeBeaconRxCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeBeaconRxCountWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributeBeaconRxCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBeaconRxCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributePacketMulticastRxCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    [self readAttributePacketMulticastRxCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributePacketMulticastRxCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                                         params:(MTRSubscribeParams * _Nullable)params
                                        subscriptionEstablished:
                                            (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePacketMulticastRxCountWithParams:subscribeParams
                                     subscriptionEstablished:subscriptionEstablishedHandler
                                               reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   reportHandler(static_cast<NSNumber *>(value), error);
                                               }];
}
+ (void)readAttributePacketMulticastRxCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                            completionHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePacketMulticastRxCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                          endpoint:endpoint
                                                             queue:queue
                                                        completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                            // Cast is safe because subclass does not add any selectors.
                                                            completionHandler(static_cast<NSNumber *>(value), error);
                                                        }];
}

- (void)readAttributePacketMulticastTxCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    [self readAttributePacketMulticastTxCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributePacketMulticastTxCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                                         params:(MTRSubscribeParams * _Nullable)params
                                        subscriptionEstablished:
                                            (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePacketMulticastTxCountWithParams:subscribeParams
                                     subscriptionEstablished:subscriptionEstablishedHandler
                                               reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   reportHandler(static_cast<NSNumber *>(value), error);
                                               }];
}
+ (void)readAttributePacketMulticastTxCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                            completionHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePacketMulticastTxCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                          endpoint:endpoint
                                                             queue:queue
                                                        completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                            // Cast is safe because subclass does not add any selectors.
                                                            completionHandler(static_cast<NSNumber *>(value), error);
                                                        }];
}

- (void)readAttributePacketUnicastRxCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributePacketUnicastRxCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributePacketUnicastRxCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePacketUnicastRxCountWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSNumber *>(value), error);
                                             }];
}
+ (void)readAttributePacketUnicastRxCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePacketUnicastRxCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSNumber *>(value), error);
                                                      }];
}

- (void)readAttributePacketUnicastTxCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributePacketUnicastTxCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributePacketUnicastTxCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePacketUnicastTxCountWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSNumber *>(value), error);
                                             }];
}
+ (void)readAttributePacketUnicastTxCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePacketUnicastTxCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSNumber *>(value), error);
                                                      }];
}

- (void)readAttributeCurrentMaxRateWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentMaxRateWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeCurrentMaxRateWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeCurrentMaxRateWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSNumber *>(value), error);
                                       }];
}
+ (void)readAttributeCurrentMaxRateWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentMaxRateWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSNumber *>(value), error);
                                                }];
}

- (void)readAttributeOverrunCountWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOverrunCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeOverrunCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeOverrunCountWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributeOverrunCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOverrunCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterEthernetNetworkDiagnostics

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)resetCountsWithCompletion:(MTRStatusCompletion)completion
{
    [self resetCountsWithParams:nil completion:completion];
}
- (void)resetCountsWithParams:(MTREthernetNetworkDiagnosticsClusterResetCountsParams * _Nullable)params
                   completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            EthernetNetworkDiagnostics::Commands::ResetCounts::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributePHYRateWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = EthernetNetworkDiagnostics::Attributes::PHYRate::TypeInfo;
    return MTRReadAttribute<MTRNullableEthernetNetworkDiagnosticsClusterPHYRateEnumAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePHYRateWithParams:(MTRSubscribeParams * _Nonnull)params
                    subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                              reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = EthernetNetworkDiagnostics::Attributes::PHYRate::TypeInfo;
    MTRSubscribeAttribute<MTRNullableEthernetNetworkDiagnosticsClusterPHYRateEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributePHYRateWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                       completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableEthernetNetworkDiagnosticsClusterPHYRateEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(NullableEthernetNetworkDiagnosticsClusterPHYRateEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = EthernetNetworkDiagnostics::Attributes::PHYRate::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFullDuplexWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = EthernetNetworkDiagnostics::Attributes::FullDuplex::TypeInfo;
    return MTRReadAttribute<MTRNullableBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFullDuplexWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = EthernetNetworkDiagnostics::Attributes::FullDuplex::TypeInfo;
    MTRSubscribeAttribute<MTRNullableBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFullDuplexWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableBooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = EthernetNetworkDiagnostics::Attributes::FullDuplex::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePacketRxCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = EthernetNetworkDiagnostics::Attributes::PacketRxCount::TypeInfo;
    return MTRReadAttribute<MTRInt64uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePacketRxCountWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = EthernetNetworkDiagnostics::Attributes::PacketRxCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt64uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePacketRxCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt64uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int64uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = EthernetNetworkDiagnostics::Attributes::PacketRxCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePacketTxCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = EthernetNetworkDiagnostics::Attributes::PacketTxCount::TypeInfo;
    return MTRReadAttribute<MTRInt64uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePacketTxCountWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = EthernetNetworkDiagnostics::Attributes::PacketTxCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt64uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePacketTxCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt64uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int64uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = EthernetNetworkDiagnostics::Attributes::PacketTxCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeTxErrCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = EthernetNetworkDiagnostics::Attributes::TxErrCount::TypeInfo;
    return MTRReadAttribute<MTRInt64uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeTxErrCountWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = EthernetNetworkDiagnostics::Attributes::TxErrCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt64uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeTxErrCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt64uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int64uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = EthernetNetworkDiagnostics::Attributes::TxErrCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCollisionCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = EthernetNetworkDiagnostics::Attributes::CollisionCount::TypeInfo;
    return MTRReadAttribute<MTRInt64uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeCollisionCountWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = EthernetNetworkDiagnostics::Attributes::CollisionCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt64uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeCollisionCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt64uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int64uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = EthernetNetworkDiagnostics::Attributes::CollisionCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeOverrunCountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = EthernetNetworkDiagnostics::Attributes::OverrunCount::TypeInfo;
    return MTRReadAttribute<MTRInt64uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeOverrunCountWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = EthernetNetworkDiagnostics::Attributes::OverrunCount::TypeInfo;
    MTRSubscribeAttribute<MTRInt64uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeOverrunCountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt64uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int64uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = EthernetNetworkDiagnostics::Attributes::OverrunCount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCarrierDetectWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = EthernetNetworkDiagnostics::Attributes::CarrierDetect::TypeInfo;
    return MTRReadAttribute<MTRNullableBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeCarrierDetectWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = EthernetNetworkDiagnostics::Attributes::CarrierDetect::TypeInfo;
    MTRSubscribeAttribute<MTRNullableBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeCarrierDetectWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableBooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = EthernetNetworkDiagnostics::Attributes::CarrierDetect::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeTimeSinceResetWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = EthernetNetworkDiagnostics::Attributes::TimeSinceReset::TypeInfo;
    return MTRReadAttribute<MTRInt64uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeTimeSinceResetWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = EthernetNetworkDiagnostics::Attributes::TimeSinceReset::TypeInfo;
    MTRSubscribeAttribute<MTRInt64uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeTimeSinceResetWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt64uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int64uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = EthernetNetworkDiagnostics::Attributes::TimeSinceReset::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = EthernetNetworkDiagnostics::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTREthernetNetworkDiagnosticsGeneratedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = EthernetNetworkDiagnostics::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTREthernetNetworkDiagnosticsGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTREthernetNetworkDiagnosticsGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(EthernetNetworkDiagnosticsGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = EthernetNetworkDiagnostics::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = EthernetNetworkDiagnostics::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTREthernetNetworkDiagnosticsAcceptedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = EthernetNetworkDiagnostics::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTREthernetNetworkDiagnosticsAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTREthernetNetworkDiagnosticsAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(EthernetNetworkDiagnosticsAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = EthernetNetworkDiagnostics::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = EthernetNetworkDiagnostics::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTREthernetNetworkDiagnosticsEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = EthernetNetworkDiagnostics::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTREthernetNetworkDiagnosticsEventListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTREthernetNetworkDiagnosticsEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(EthernetNetworkDiagnosticsEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = EthernetNetworkDiagnostics::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = EthernetNetworkDiagnostics::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTREthernetNetworkDiagnosticsAttributeListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = EthernetNetworkDiagnostics::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTREthernetNetworkDiagnosticsAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTREthernetNetworkDiagnosticsAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(EthernetNetworkDiagnosticsAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = EthernetNetworkDiagnostics::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = EthernetNetworkDiagnostics::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = EthernetNetworkDiagnostics::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = EthernetNetworkDiagnostics::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = EthernetNetworkDiagnostics::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = EthernetNetworkDiagnostics::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = EthernetNetworkDiagnostics::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterEthernetNetworkDiagnostics (Deprecated)

- (void)resetCountsWithParams:(MTREthernetNetworkDiagnosticsClusterResetCountsParams * _Nullable)params
            completionHandler:(MTRStatusCompletion)completionHandler
{
    [self resetCountsWithParams:params completion:completionHandler];
}
- (void)resetCountsWithCompletionHandler:(MTRStatusCompletion)completionHandler
{
    [self resetCountsWithParams:nil completionHandler:completionHandler];
}

- (void)readAttributePHYRateWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePHYRateWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributePHYRateWithMinInterval:(NSNumber * _Nonnull)minInterval
                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                          params:(MTRSubscribeParams * _Nullable)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePHYRateWithParams:subscribeParams
                      subscriptionEstablished:subscriptionEstablishedHandler
                                reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                    // Cast is safe because subclass does not add any selectors.
                                    reportHandler(static_cast<NSNumber *>(value), error);
                                }];
}
+ (void)readAttributePHYRateWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                      endpoint:(NSNumber *)endpoint
                                         queue:(dispatch_queue_t)queue
                             completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePHYRateWithClusterStateCache:attributeCacheContainer.realContainer
                                           endpoint:endpoint
                                              queue:queue
                                         completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             completionHandler(static_cast<NSNumber *>(value), error);
                                         }];
}

- (void)readAttributeFullDuplexWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFullDuplexWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFullDuplexWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFullDuplexWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFullDuplexWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFullDuplexWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributePacketRxCountWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePacketRxCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributePacketRxCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePacketRxCountWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributePacketRxCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePacketRxCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributePacketTxCountWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePacketTxCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributePacketTxCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePacketTxCountWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributePacketTxCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePacketTxCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributeTxErrCountWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeTxErrCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeTxErrCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeTxErrCountWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeTxErrCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeTxErrCountWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeCollisionCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeCollisionCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeCollisionCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeCollisionCountWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSNumber *>(value), error);
                                       }];
}
+ (void)readAttributeCollisionCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCollisionCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSNumber *>(value), error);
                                                }];
}

- (void)readAttributeOverrunCountWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOverrunCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeOverrunCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeOverrunCountWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributeOverrunCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOverrunCountWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributeCarrierDetectWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCarrierDetectWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeCarrierDetectWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeCarrierDetectWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributeCarrierDetectWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCarrierDetectWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributeTimeSinceResetWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeTimeSinceResetWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeTimeSinceResetWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeTimeSinceResetWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSNumber *>(value), error);
                                       }];
}
+ (void)readAttributeTimeSinceResetWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeTimeSinceResetWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSNumber *>(value), error);
                                                }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterBridgedDeviceBasicInformation

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)readAttributeVendorNameWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::VendorName::TypeInfo;
    return MTRReadAttribute<MTRCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeVendorNameWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::VendorName::TypeInfo;
    MTRSubscribeAttribute<MTRCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeVendorNameWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(CharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BridgedDeviceBasicInformation::Attributes::VendorName::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeVendorIDWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::VendorID::TypeInfo;
    return MTRReadAttribute<MTRVendorIdAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeVendorIDWithParams:(MTRSubscribeParams * _Nonnull)params
                     subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                               reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::VendorID::TypeInfo;
    MTRSubscribeAttribute<MTRVendorIdAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeVendorIDWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                        completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRVendorIdAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(VendorIdAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BridgedDeviceBasicInformation::Attributes::VendorID::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeProductNameWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::ProductName::TypeInfo;
    return MTRReadAttribute<MTRCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeProductNameWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::ProductName::TypeInfo;
    MTRSubscribeAttribute<MTRCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeProductNameWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(CharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BridgedDeviceBasicInformation::Attributes::ProductName::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNodeLabelWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::NodeLabel::TypeInfo;
    return MTRReadAttribute<MTRCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeNodeLabelWithValue:(NSString * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeNodeLabelWithValue:(NSString * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeNodeLabelWithValue:(NSString * _Nonnull)value
                                  params:(MTRWriteParams * _Nullable)params
                              completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BridgedDeviceBasicInformation::Attributes::NodeLabel::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = [self asCharSpan:value];

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeNodeLabelWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::NodeLabel::TypeInfo;
    MTRSubscribeAttribute<MTRCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNodeLabelWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(CharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BridgedDeviceBasicInformation::Attributes::NodeLabel::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeHardwareVersionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::HardwareVersion::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeHardwareVersionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::HardwareVersion::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeHardwareVersionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BridgedDeviceBasicInformation::Attributes::HardwareVersion::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeHardwareVersionStringWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::HardwareVersionString::TypeInfo;
    return MTRReadAttribute<MTRCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeHardwareVersionStringWithParams:(MTRSubscribeParams * _Nonnull)params
                                  subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                            reportHandler:
                                                (void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::HardwareVersionString::TypeInfo;
    MTRSubscribeAttribute<MTRCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeHardwareVersionStringWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                                     completion:
                                                         (void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(CharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BridgedDeviceBasicInformation::Attributes::HardwareVersionString::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSoftwareVersionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::SoftwareVersion::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeSoftwareVersionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::SoftwareVersion::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeSoftwareVersionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BridgedDeviceBasicInformation::Attributes::SoftwareVersion::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSoftwareVersionStringWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::SoftwareVersionString::TypeInfo;
    return MTRReadAttribute<MTRCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeSoftwareVersionStringWithParams:(MTRSubscribeParams * _Nonnull)params
                                  subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                            reportHandler:
                                                (void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::SoftwareVersionString::TypeInfo;
    MTRSubscribeAttribute<MTRCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeSoftwareVersionStringWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                                     completion:
                                                         (void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(CharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BridgedDeviceBasicInformation::Attributes::SoftwareVersionString::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeManufacturingDateWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::ManufacturingDate::TypeInfo;
    return MTRReadAttribute<MTRCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeManufacturingDateWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::ManufacturingDate::TypeInfo;
    MTRSubscribeAttribute<MTRCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeManufacturingDateWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(CharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BridgedDeviceBasicInformation::Attributes::ManufacturingDate::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePartNumberWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::PartNumber::TypeInfo;
    return MTRReadAttribute<MTRCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePartNumberWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::PartNumber::TypeInfo;
    MTRSubscribeAttribute<MTRCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePartNumberWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(CharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BridgedDeviceBasicInformation::Attributes::PartNumber::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeProductURLWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::ProductURL::TypeInfo;
    return MTRReadAttribute<MTRCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeProductURLWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::ProductURL::TypeInfo;
    MTRSubscribeAttribute<MTRCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeProductURLWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(CharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BridgedDeviceBasicInformation::Attributes::ProductURL::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeProductLabelWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::ProductLabel::TypeInfo;
    return MTRReadAttribute<MTRCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeProductLabelWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::ProductLabel::TypeInfo;
    MTRSubscribeAttribute<MTRCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeProductLabelWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(CharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BridgedDeviceBasicInformation::Attributes::ProductLabel::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSerialNumberWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::SerialNumber::TypeInfo;
    return MTRReadAttribute<MTRCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeSerialNumberWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::SerialNumber::TypeInfo;
    MTRSubscribeAttribute<MTRCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeSerialNumberWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(CharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BridgedDeviceBasicInformation::Attributes::SerialNumber::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeReachableWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::Reachable::TypeInfo;
    return MTRReadAttribute<MTRBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeReachableWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::Reachable::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeReachableWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BridgedDeviceBasicInformation::Attributes::Reachable::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeUniqueIDWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::UniqueID::TypeInfo;
    return MTRReadAttribute<MTRCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeUniqueIDWithParams:(MTRSubscribeParams * _Nonnull)params
                     subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                               reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::UniqueID::TypeInfo;
    MTRSubscribeAttribute<MTRCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeUniqueIDWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                        completion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(CharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BridgedDeviceBasicInformation::Attributes::UniqueID::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeProductAppearanceWithCompletion:
    (void (^)(
        MTRBridgedDeviceBasicInformationClusterProductAppearanceStruct * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::ProductAppearance::TypeInfo;
    return MTRReadAttribute<MTRBridgedDeviceBasicInformationProductAppearanceStructAttributeCallbackBridge,
        MTRBridgedDeviceBasicInformationClusterProductAppearanceStruct, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeProductAppearanceWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:
                                            (void (^)(
                                                MTRBridgedDeviceBasicInformationClusterProductAppearanceStruct * _Nullable value,
                                                NSError * _Nullable error))reportHandler
{
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::ProductAppearance::TypeInfo;
    MTRSubscribeAttribute<MTRBridgedDeviceBasicInformationProductAppearanceStructAttributeCallbackSubscriptionBridge,
        MTRBridgedDeviceBasicInformationClusterProductAppearanceStruct, TypeInfo::DecodableType>(params, subscriptionEstablished,
        reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)
    readAttributeProductAppearanceWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:
                                                 (void (^)(
                                                     MTRBridgedDeviceBasicInformationClusterProductAppearanceStruct * _Nullable value,
                                                     NSError * _Nullable error))completion
{
    auto * bridge = new MTRBridgedDeviceBasicInformationProductAppearanceStructAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(BridgedDeviceBasicInformationProductAppearanceStructAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BridgedDeviceBasicInformation::Attributes::ProductAppearance::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRBridgedDeviceBasicInformationGeneratedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRBridgedDeviceBasicInformationGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBridgedDeviceBasicInformationGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(BridgedDeviceBasicInformationGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BridgedDeviceBasicInformation::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRBridgedDeviceBasicInformationAcceptedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRBridgedDeviceBasicInformationAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBridgedDeviceBasicInformationAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(BridgedDeviceBasicInformationAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BridgedDeviceBasicInformation::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRBridgedDeviceBasicInformationEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRBridgedDeviceBasicInformationEventListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBridgedDeviceBasicInformationEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(BridgedDeviceBasicInformationEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BridgedDeviceBasicInformation::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRBridgedDeviceBasicInformationAttributeListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRBridgedDeviceBasicInformationAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBridgedDeviceBasicInformationAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(BridgedDeviceBasicInformationAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BridgedDeviceBasicInformation::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BridgedDeviceBasicInformation::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BridgedDeviceBasicInformation::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BridgedDeviceBasicInformation::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterBridgedDeviceBasic
@end

@implementation MTRBaseClusterBridgedDeviceBasic (Deprecated)

- (void)readAttributeVendorNameWithCompletionHandler:(void (^)(
                                                         NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeVendorNameWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)subscribeAttributeVendorNameWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeVendorNameWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSString *>(value), error);
                                   }];
}
+ (void)readAttributeVendorNameWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeVendorNameWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSString *>(value), error);
                                            }];
}

- (void)readAttributeVendorIDWithCompletionHandler:(void (^)(
                                                       NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeVendorIDWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeVendorIDWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeVendorIDWithParams:subscribeParams
                       subscriptionEstablished:subscriptionEstablishedHandler
                                 reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                     // Cast is safe because subclass does not add any selectors.
                                     reportHandler(static_cast<NSNumber *>(value), error);
                                 }];
}
+ (void)readAttributeVendorIDWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeVendorIDWithClusterStateCache:attributeCacheContainer.realContainer
                                            endpoint:endpoint
                                               queue:queue
                                          completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              completionHandler(static_cast<NSNumber *>(value), error);
                                          }];
}

- (void)readAttributeProductNameWithCompletionHandler:(void (^)(
                                                          NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeProductNameWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)subscribeAttributeProductNameWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeProductNameWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSString *>(value), error);
                                    }];
}
+ (void)readAttributeProductNameWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeProductNameWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSString *>(value), error);
                                             }];
}

- (void)readAttributeNodeLabelWithCompletionHandler:(void (^)(
                                                        NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNodeLabelWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)writeAttributeNodeLabelWithValue:(NSString * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNodeLabelWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeNodeLabelWithValue:(NSString * _Nonnull)value
                                  params:(MTRWriteParams * _Nullable)params
                       completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNodeLabelWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeNodeLabelWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNodeLabelWithParams:subscribeParams
                        subscriptionEstablished:subscriptionEstablishedHandler
                                  reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                      // Cast is safe because subclass does not add any selectors.
                                      reportHandler(static_cast<NSString *>(value), error);
                                  }];
}
+ (void)readAttributeNodeLabelWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNodeLabelWithClusterStateCache:attributeCacheContainer.realContainer
                                             endpoint:endpoint
                                                queue:queue
                                           completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               completionHandler(static_cast<NSString *>(value), error);
                                           }];
}

- (void)readAttributeHardwareVersionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeHardwareVersionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeHardwareVersionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeHardwareVersionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeHardwareVersionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeHardwareVersionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (void)readAttributeHardwareVersionStringWithCompletionHandler:(void (^)(NSString * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    [self readAttributeHardwareVersionStringWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)subscribeAttributeHardwareVersionStringWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeHardwareVersionStringWithParams:subscribeParams
                                    subscriptionEstablished:subscriptionEstablishedHandler
                                              reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  reportHandler(static_cast<NSString *>(value), error);
                                              }];
}
+ (void)readAttributeHardwareVersionStringWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeHardwareVersionStringWithClusterStateCache:attributeCacheContainer.realContainer
                                                         endpoint:endpoint
                                                            queue:queue
                                                       completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                                           // Cast is safe because subclass does not add any selectors.
                                                           completionHandler(static_cast<NSString *>(value), error);
                                                       }];
}

- (void)readAttributeSoftwareVersionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeSoftwareVersionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeSoftwareVersionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeSoftwareVersionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeSoftwareVersionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSoftwareVersionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (void)readAttributeSoftwareVersionStringWithCompletionHandler:(void (^)(NSString * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    [self readAttributeSoftwareVersionStringWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)subscribeAttributeSoftwareVersionStringWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeSoftwareVersionStringWithParams:subscribeParams
                                    subscriptionEstablished:subscriptionEstablishedHandler
                                              reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  reportHandler(static_cast<NSString *>(value), error);
                                              }];
}
+ (void)readAttributeSoftwareVersionStringWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSoftwareVersionStringWithClusterStateCache:attributeCacheContainer.realContainer
                                                         endpoint:endpoint
                                                            queue:queue
                                                       completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                                           // Cast is safe because subclass does not add any selectors.
                                                           completionHandler(static_cast<NSString *>(value), error);
                                                       }];
}

- (void)readAttributeManufacturingDateWithCompletionHandler:(void (^)(NSString * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeManufacturingDateWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)subscribeAttributeManufacturingDateWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeManufacturingDateWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSString *>(value), error);
                                          }];
}
+ (void)readAttributeManufacturingDateWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeManufacturingDateWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSString *>(value), error);
                                                   }];
}

- (void)readAttributePartNumberWithCompletionHandler:(void (^)(
                                                         NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePartNumberWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)subscribeAttributePartNumberWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePartNumberWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSString *>(value), error);
                                   }];
}
+ (void)readAttributePartNumberWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePartNumberWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSString *>(value), error);
                                            }];
}

- (void)readAttributeProductURLWithCompletionHandler:(void (^)(
                                                         NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeProductURLWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)subscribeAttributeProductURLWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeProductURLWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSString *>(value), error);
                                   }];
}
+ (void)readAttributeProductURLWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeProductURLWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSString *>(value), error);
                                            }];
}

- (void)readAttributeProductLabelWithCompletionHandler:(void (^)(
                                                           NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeProductLabelWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)subscribeAttributeProductLabelWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeProductLabelWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSString *>(value), error);
                                     }];
}
+ (void)readAttributeProductLabelWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeProductLabelWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSString *>(value), error);
                                              }];
}

- (void)readAttributeSerialNumberWithCompletionHandler:(void (^)(
                                                           NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSerialNumberWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)subscribeAttributeSerialNumberWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeSerialNumberWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSString *>(value), error);
                                     }];
}
+ (void)readAttributeSerialNumberWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSerialNumberWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSString *>(value), error);
                                              }];
}

- (void)readAttributeReachableWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeReachableWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeReachableWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeReachableWithParams:subscribeParams
                        subscriptionEstablished:subscriptionEstablishedHandler
                                  reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                      // Cast is safe because subclass does not add any selectors.
                                      reportHandler(static_cast<NSNumber *>(value), error);
                                  }];
}
+ (void)readAttributeReachableWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeReachableWithClusterStateCache:attributeCacheContainer.realContainer
                                             endpoint:endpoint
                                                queue:queue
                                           completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               completionHandler(static_cast<NSNumber *>(value), error);
                                           }];
}

- (void)readAttributeUniqueIDWithCompletionHandler:(void (^)(
                                                       NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeUniqueIDWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)subscribeAttributeUniqueIDWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeUniqueIDWithParams:subscribeParams
                       subscriptionEstablished:subscriptionEstablishedHandler
                                 reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                     // Cast is safe because subclass does not add any selectors.
                                     reportHandler(static_cast<NSString *>(value), error);
                                 }];
}
+ (void)readAttributeUniqueIDWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeUniqueIDWithClusterStateCache:attributeCacheContainer.realContainer
                                            endpoint:endpoint
                                               queue:queue
                                          completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              completionHandler(static_cast<NSString *>(value), error);
                                          }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterSwitch

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)readAttributeNumberOfPositionsWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Switch::Attributes::NumberOfPositions::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeNumberOfPositionsWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Switch::Attributes::NumberOfPositions::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNumberOfPositionsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Switch::Attributes::NumberOfPositions::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCurrentPositionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Switch::Attributes::CurrentPosition::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeCurrentPositionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Switch::Attributes::CurrentPosition::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeCurrentPositionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Switch::Attributes::CurrentPosition::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMultiPressMaxWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Switch::Attributes::MultiPressMax::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMultiPressMaxWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Switch::Attributes::MultiPressMax::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMultiPressMaxWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Switch::Attributes::MultiPressMax::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Switch::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRSwitchGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Switch::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRSwitchGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRSwitchGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(SwitchGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Switch::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Switch::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRSwitchAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Switch::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRSwitchAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRSwitchAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(SwitchAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Switch::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Switch::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRSwitchEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Switch::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRSwitchEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRSwitchEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(SwitchEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Switch::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Switch::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRSwitchAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Switch::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRSwitchAttributeListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRSwitchAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(SwitchAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Switch::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Switch::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Switch::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Switch::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Switch::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Switch::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Switch::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterSwitch (Deprecated)

- (void)readAttributeNumberOfPositionsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeNumberOfPositionsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeNumberOfPositionsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNumberOfPositionsWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSNumber *>(value), error);
                                          }];
}
+ (void)readAttributeNumberOfPositionsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNumberOfPositionsWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}

- (void)readAttributeCurrentPositionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentPositionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeCurrentPositionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeCurrentPositionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeCurrentPositionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentPositionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (void)readAttributeMultiPressMaxWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMultiPressMaxWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeMultiPressMaxWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMultiPressMaxWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributeMultiPressMaxWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMultiPressMaxWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterAdministratorCommissioning

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)openCommissioningWindowWithParams:(MTRAdministratorCommissioningClusterOpenCommissioningWindowParams *)params
                               completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            AdministratorCommissioning::Commands::OpenCommissioningWindow::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            if (!timedInvokeTimeoutMs.HasValue()) {
                timedInvokeTimeoutMs.SetValue(10000);
            }
            request.commissioningTimeout = params.commissioningTimeout.unsignedShortValue;
            request.PAKEPasscodeVerifier = [self asByteSpan:params.pakePasscodeVerifier];
            request.discriminator = params.discriminator.unsignedShortValue;
            request.iterations = params.iterations.unsignedIntValue;
            request.salt = [self asByteSpan:params.salt];

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)openBasicCommissioningWindowWithParams:(MTRAdministratorCommissioningClusterOpenBasicCommissioningWindowParams *)params
                                    completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            AdministratorCommissioning::Commands::OpenBasicCommissioningWindow::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            if (!timedInvokeTimeoutMs.HasValue()) {
                timedInvokeTimeoutMs.SetValue(10000);
            }
            request.commissioningTimeout = params.commissioningTimeout.unsignedShortValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)revokeCommissioningWithCompletion:(MTRStatusCompletion)completion
{
    [self revokeCommissioningWithParams:nil completion:completion];
}
- (void)revokeCommissioningWithParams:(MTRAdministratorCommissioningClusterRevokeCommissioningParams * _Nullable)params
                           completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            AdministratorCommissioning::Commands::RevokeCommissioning::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            if (!timedInvokeTimeoutMs.HasValue()) {
                timedInvokeTimeoutMs.SetValue(10000);
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeWindowStatusWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = AdministratorCommissioning::Attributes::WindowStatus::TypeInfo;
    return MTRReadAttribute<MTRAdministratorCommissioningClusterCommissioningWindowStatusEnumAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeWindowStatusWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = AdministratorCommissioning::Attributes::WindowStatus::TypeInfo;
    MTRSubscribeAttribute<MTRAdministratorCommissioningClusterCommissioningWindowStatusEnumAttributeCallbackSubscriptionBridge,
        NSNumber, TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device,
        self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeWindowStatusWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRAdministratorCommissioningClusterCommissioningWindowStatusEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(AdministratorCommissioningClusterCommissioningWindowStatusEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AdministratorCommissioning::Attributes::WindowStatus::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAdminFabricIndexWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = AdministratorCommissioning::Attributes::AdminFabricIndex::TypeInfo;
    return MTRReadAttribute<MTRNullableInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAdminFabricIndexWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = AdministratorCommissioning::Attributes::AdminFabricIndex::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAdminFabricIndexWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AdministratorCommissioning::Attributes::AdminFabricIndex::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAdminVendorIdWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = AdministratorCommissioning::Attributes::AdminVendorId::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAdminVendorIdWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = AdministratorCommissioning::Attributes::AdminVendorId::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAdminVendorIdWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AdministratorCommissioning::Attributes::AdminVendorId::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = AdministratorCommissioning::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRAdministratorCommissioningGeneratedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = AdministratorCommissioning::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRAdministratorCommissioningGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRAdministratorCommissioningGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(AdministratorCommissioningGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AdministratorCommissioning::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = AdministratorCommissioning::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRAdministratorCommissioningAcceptedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = AdministratorCommissioning::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRAdministratorCommissioningAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRAdministratorCommissioningAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(AdministratorCommissioningAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AdministratorCommissioning::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = AdministratorCommissioning::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRAdministratorCommissioningEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = AdministratorCommissioning::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRAdministratorCommissioningEventListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRAdministratorCommissioningEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(AdministratorCommissioningEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AdministratorCommissioning::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = AdministratorCommissioning::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRAdministratorCommissioningAttributeListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = AdministratorCommissioning::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRAdministratorCommissioningAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRAdministratorCommissioningAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(AdministratorCommissioningAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AdministratorCommissioning::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = AdministratorCommissioning::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = AdministratorCommissioning::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AdministratorCommissioning::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = AdministratorCommissioning::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = AdministratorCommissioning::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AdministratorCommissioning::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterAdministratorCommissioning (Deprecated)

- (void)openCommissioningWindowWithParams:(MTRAdministratorCommissioningClusterOpenCommissioningWindowParams *)params
                        completionHandler:(MTRStatusCompletion)completionHandler
{
    [self openCommissioningWindowWithParams:params completion:completionHandler];
}
- (void)openBasicCommissioningWindowWithParams:(MTRAdministratorCommissioningClusterOpenBasicCommissioningWindowParams *)params
                             completionHandler:(MTRStatusCompletion)completionHandler
{
    [self openBasicCommissioningWindowWithParams:params completion:completionHandler];
}
- (void)revokeCommissioningWithParams:(MTRAdministratorCommissioningClusterRevokeCommissioningParams * _Nullable)params
                    completionHandler:(MTRStatusCompletion)completionHandler
{
    [self revokeCommissioningWithParams:params completion:completionHandler];
}
- (void)revokeCommissioningWithCompletionHandler:(MTRStatusCompletion)completionHandler
{
    [self revokeCommissioningWithParams:nil completionHandler:completionHandler];
}

- (void)readAttributeWindowStatusWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeWindowStatusWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeWindowStatusWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeWindowStatusWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributeWindowStatusWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeWindowStatusWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributeAdminFabricIndexWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeAdminFabricIndexWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)
    subscribeAttributeAdminFabricIndexWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAdminFabricIndexWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributeAdminFabricIndexWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAdminFabricIndexWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeAdminVendorIdWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAdminVendorIdWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeAdminVendorIdWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAdminVendorIdWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributeAdminVendorIdWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAdminVendorIdWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterOperationalCredentials

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)attestationRequestWithParams:(MTROperationalCredentialsClusterAttestationRequestParams *)params
                          completion:(void (^)(MTROperationalCredentialsClusterAttestationResponseParams * _Nullable data,
                                         NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTROperationalCredentialsClusterAttestationResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            OperationalCredentialsClusterAttestationResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTROperationalCredentialsClusterAttestationResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            OperationalCredentials::Commands::AttestationRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.attestationNonce = [self asByteSpan:params.attestationNonce];

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)certificateChainRequestWithParams:(MTROperationalCredentialsClusterCertificateChainRequestParams *)params
                               completion:(void (^)(MTROperationalCredentialsClusterCertificateChainResponseParams * _Nullable data,
                                              NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTROperationalCredentialsClusterCertificateChainResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            OperationalCredentialsClusterCertificateChainResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTROperationalCredentialsClusterCertificateChainResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            OperationalCredentials::Commands::CertificateChainRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.certificateType
                = static_cast<std::remove_reference_t<decltype(request.certificateType)>>(params.certificateType.unsignedCharValue);

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)CSRRequestWithParams:(MTROperationalCredentialsClusterCSRRequestParams *)params
                  completion:(void (^)(MTROperationalCredentialsClusterCSRResponseParams * _Nullable data,
                                 NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTROperationalCredentialsClusterCSRResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            OperationalCredentialsClusterCSRResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTROperationalCredentialsClusterCSRResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            OperationalCredentials::Commands::CSRRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.CSRNonce = [self asByteSpan:params.csrNonce];
            if (params.isForUpdateNOC != nil) {
                auto & definedValue_0 = request.isForUpdateNOC.Emplace();
                definedValue_0 = params.isForUpdateNOC.boolValue;
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)addNOCWithParams:(MTROperationalCredentialsClusterAddNOCParams *)params
              completion:(void (^)(MTROperationalCredentialsClusterNOCResponseParams * _Nullable data,
                             NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTROperationalCredentialsClusterNOCResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            OperationalCredentialsClusterNOCResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTROperationalCredentialsClusterNOCResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            OperationalCredentials::Commands::AddNOC::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.NOCValue = [self asByteSpan:params.nocValue];
            if (params.icacValue != nil) {
                auto & definedValue_0 = request.ICACValue.Emplace();
                definedValue_0 = [self asByteSpan:params.icacValue];
            }
            request.IPKValue = [self asByteSpan:params.ipkValue];
            request.caseAdminSubject = params.caseAdminSubject.unsignedLongLongValue;
            request.adminVendorId
                = static_cast<std::remove_reference_t<decltype(request.adminVendorId)>>(params.adminVendorId.unsignedShortValue);

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)updateNOCWithParams:(MTROperationalCredentialsClusterUpdateNOCParams *)params
                 completion:(void (^)(MTROperationalCredentialsClusterNOCResponseParams * _Nullable data,
                                NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTROperationalCredentialsClusterNOCResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            OperationalCredentialsClusterNOCResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTROperationalCredentialsClusterNOCResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            OperationalCredentials::Commands::UpdateNOC::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.NOCValue = [self asByteSpan:params.nocValue];
            if (params.icacValue != nil) {
                auto & definedValue_0 = request.ICACValue.Emplace();
                definedValue_0 = [self asByteSpan:params.icacValue];
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)updateFabricLabelWithParams:(MTROperationalCredentialsClusterUpdateFabricLabelParams *)params
                         completion:(void (^)(MTROperationalCredentialsClusterNOCResponseParams * _Nullable data,
                                        NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTROperationalCredentialsClusterNOCResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            OperationalCredentialsClusterNOCResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTROperationalCredentialsClusterNOCResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            OperationalCredentials::Commands::UpdateFabricLabel::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.label = [self asCharSpan:params.label];

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)removeFabricWithParams:(MTROperationalCredentialsClusterRemoveFabricParams *)params
                    completion:(void (^)(MTROperationalCredentialsClusterNOCResponseParams * _Nullable data,
                                   NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTROperationalCredentialsClusterNOCResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            OperationalCredentialsClusterNOCResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTROperationalCredentialsClusterNOCResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            OperationalCredentials::Commands::RemoveFabric::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.fabricIndex = params.fabricIndex.unsignedCharValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)addTrustedRootCertificateWithParams:(MTROperationalCredentialsClusterAddTrustedRootCertificateParams *)params
                                 completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            OperationalCredentials::Commands::AddTrustedRootCertificate::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.rootCACertificate = [self asByteSpan:params.rootCACertificate];

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeNOCsWithParams:(MTRReadParams * _Nullable)params
                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{ // Make a copy of params before we go async.
    params = [params copy];
    using TypeInfo = OperationalCredentials::Attributes::NOCs::TypeInfo;
    return MTRReadAttribute<MTROperationalCredentialsNOCsListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeNOCsWithParams:(MTRSubscribeParams * _Nonnull)params
                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                           reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OperationalCredentials::Attributes::NOCs::TypeInfo;
    MTRSubscribeAttribute<MTROperationalCredentialsNOCsListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNOCsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                      endpoint:(NSNumber *)endpoint
                                         queue:(dispatch_queue_t)queue
                                    completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTROperationalCredentialsNOCsListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(OperationalCredentialsNOCsListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OperationalCredentials::Attributes::NOCs::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFabricsWithParams:(MTRReadParams * _Nullable)params
                            completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{ // Make a copy of params before we go async.
    params = [params copy];
    using TypeInfo = OperationalCredentials::Attributes::Fabrics::TypeInfo;
    return MTRReadAttribute<MTROperationalCredentialsFabricsListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFabricsWithParams:(MTRSubscribeParams * _Nonnull)params
                    subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                              reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OperationalCredentials::Attributes::Fabrics::TypeInfo;
    MTRSubscribeAttribute<MTROperationalCredentialsFabricsListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeFabricsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                       completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTROperationalCredentialsFabricsListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(OperationalCredentialsFabricsListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OperationalCredentials::Attributes::Fabrics::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSupportedFabricsWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OperationalCredentials::Attributes::SupportedFabrics::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeSupportedFabricsWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OperationalCredentials::Attributes::SupportedFabrics::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeSupportedFabricsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OperationalCredentials::Attributes::SupportedFabrics::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCommissionedFabricsWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OperationalCredentials::Attributes::CommissionedFabrics::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeCommissionedFabricsWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OperationalCredentials::Attributes::CommissionedFabrics::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeCommissionedFabricsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OperationalCredentials::Attributes::CommissionedFabrics::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeTrustedRootCertificatesWithCompletion:(void (^)(
                                                               NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OperationalCredentials::Attributes::TrustedRootCertificates::TypeInfo;
    return MTRReadAttribute<MTROperationalCredentialsTrustedRootCertificatesListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeTrustedRootCertificatesWithParams:(MTRSubscribeParams * _Nonnull)params
                                    subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                              reportHandler:
                                                  (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OperationalCredentials::Attributes::TrustedRootCertificates::TypeInfo;
    MTRSubscribeAttribute<MTROperationalCredentialsTrustedRootCertificatesListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeTrustedRootCertificatesWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                         endpoint:(NSNumber *)endpoint
                                                            queue:(dispatch_queue_t)queue
                                                       completion:(void (^)(NSArray * _Nullable value,
                                                                      NSError * _Nullable error))completion
{
    auto * bridge = new MTROperationalCredentialsTrustedRootCertificatesListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(OperationalCredentialsTrustedRootCertificatesListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OperationalCredentials::Attributes::TrustedRootCertificates::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCurrentFabricIndexWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OperationalCredentials::Attributes::CurrentFabricIndex::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeCurrentFabricIndexWithParams:(MTRSubscribeParams * _Nonnull)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OperationalCredentials::Attributes::CurrentFabricIndex::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeCurrentFabricIndexWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                                  completion:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OperationalCredentials::Attributes::CurrentFabricIndex::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OperationalCredentials::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTROperationalCredentialsGeneratedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OperationalCredentials::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTROperationalCredentialsGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTROperationalCredentialsGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(OperationalCredentialsGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OperationalCredentials::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OperationalCredentials::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTROperationalCredentialsAcceptedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OperationalCredentials::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTROperationalCredentialsAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTROperationalCredentialsAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(OperationalCredentialsAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OperationalCredentials::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OperationalCredentials::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTROperationalCredentialsEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OperationalCredentials::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTROperationalCredentialsEventListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTROperationalCredentialsEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(OperationalCredentialsEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OperationalCredentials::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OperationalCredentials::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTROperationalCredentialsAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OperationalCredentials::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTROperationalCredentialsAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTROperationalCredentialsAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(OperationalCredentialsAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OperationalCredentials::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OperationalCredentials::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OperationalCredentials::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OperationalCredentials::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OperationalCredentials::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OperationalCredentials::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OperationalCredentials::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterOperationalCredentials (Deprecated)

- (void)attestationRequestWithParams:(MTROperationalCredentialsClusterAttestationRequestParams *)params
                   completionHandler:(void (^)(MTROperationalCredentialsClusterAttestationResponseParams * _Nullable data,
                                         NSError * _Nullable error))completionHandler
{
    [self attestationRequestWithParams:params
                            completion:^(MTROperationalCredentialsClusterAttestationResponseParams * _Nullable data,
                                NSError * _Nullable error) {
                                // Cast is safe because subclass does not add any selectors.
                                completionHandler(
                                    static_cast<MTROperationalCredentialsClusterAttestationResponseParams *>(data), error);
                            }];
}
- (void)certificateChainRequestWithParams:(MTROperationalCredentialsClusterCertificateChainRequestParams *)params
                        completionHandler:(void (^)(MTROperationalCredentialsClusterCertificateChainResponseParams * _Nullable data,
                                              NSError * _Nullable error))completionHandler
{
    [self
        certificateChainRequestWithParams:params
                               completion:^(MTROperationalCredentialsClusterCertificateChainResponseParams * _Nullable data,
                                   NSError * _Nullable error) {
                                   // Cast is safe because subclass does not add any selectors.
                                   completionHandler(
                                       static_cast<MTROperationalCredentialsClusterCertificateChainResponseParams *>(data), error);
                               }];
}
- (void)CSRRequestWithParams:(MTROperationalCredentialsClusterCSRRequestParams *)params
           completionHandler:(void (^)(MTROperationalCredentialsClusterCSRResponseParams * _Nullable data,
                                 NSError * _Nullable error))completionHandler
{
    [self CSRRequestWithParams:params
                    completion:^(MTROperationalCredentialsClusterCSRResponseParams * _Nullable data, NSError * _Nullable error) {
                        // Cast is safe because subclass does not add any selectors.
                        completionHandler(static_cast<MTROperationalCredentialsClusterCSRResponseParams *>(data), error);
                    }];
}
- (void)addNOCWithParams:(MTROperationalCredentialsClusterAddNOCParams *)params
       completionHandler:(void (^)(MTROperationalCredentialsClusterNOCResponseParams * _Nullable data,
                             NSError * _Nullable error))completionHandler
{
    [self addNOCWithParams:params
                completion:^(MTROperationalCredentialsClusterNOCResponseParams * _Nullable data, NSError * _Nullable error) {
                    // Cast is safe because subclass does not add any selectors.
                    completionHandler(static_cast<MTROperationalCredentialsClusterNOCResponseParams *>(data), error);
                }];
}
- (void)updateNOCWithParams:(MTROperationalCredentialsClusterUpdateNOCParams *)params
          completionHandler:(void (^)(MTROperationalCredentialsClusterNOCResponseParams * _Nullable data,
                                NSError * _Nullable error))completionHandler
{
    [self updateNOCWithParams:params
                   completion:^(MTROperationalCredentialsClusterNOCResponseParams * _Nullable data, NSError * _Nullable error) {
                       // Cast is safe because subclass does not add any selectors.
                       completionHandler(static_cast<MTROperationalCredentialsClusterNOCResponseParams *>(data), error);
                   }];
}
- (void)updateFabricLabelWithParams:(MTROperationalCredentialsClusterUpdateFabricLabelParams *)params
                  completionHandler:(void (^)(MTROperationalCredentialsClusterNOCResponseParams * _Nullable data,
                                        NSError * _Nullable error))completionHandler
{
    [self updateFabricLabelWithParams:params
                           completion:^(
                               MTROperationalCredentialsClusterNOCResponseParams * _Nullable data, NSError * _Nullable error) {
                               // Cast is safe because subclass does not add any selectors.
                               completionHandler(static_cast<MTROperationalCredentialsClusterNOCResponseParams *>(data), error);
                           }];
}
- (void)removeFabricWithParams:(MTROperationalCredentialsClusterRemoveFabricParams *)params
             completionHandler:(void (^)(MTROperationalCredentialsClusterNOCResponseParams * _Nullable data,
                                   NSError * _Nullable error))completionHandler
{
    [self removeFabricWithParams:params
                      completion:^(MTROperationalCredentialsClusterNOCResponseParams * _Nullable data, NSError * _Nullable error) {
                          // Cast is safe because subclass does not add any selectors.
                          completionHandler(static_cast<MTROperationalCredentialsClusterNOCResponseParams *>(data), error);
                      }];
}
- (void)addTrustedRootCertificateWithParams:(MTROperationalCredentialsClusterAddTrustedRootCertificateParams *)params
                          completionHandler:(MTRStatusCompletion)completionHandler
{
    [self addTrustedRootCertificateWithParams:params completion:completionHandler];
}

- (void)readAttributeNOCsWithParams:(MTRReadParams * _Nullable)params
                  completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNOCsWithParams:params
                           completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                               // Cast is safe because subclass does not add any selectors.
                               completionHandler(static_cast<NSArray *>(value), error);
                           }];
}
- (void)subscribeAttributeNOCsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                       params:(MTRSubscribeParams * _Nullable)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNOCsWithParams:subscribeParams
                   subscriptionEstablished:subscriptionEstablishedHandler
                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                 // Cast is safe because subclass does not add any selectors.
                                 reportHandler(static_cast<NSArray *>(value), error);
                             }];
}
+ (void)readAttributeNOCsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                   endpoint:(NSNumber *)endpoint
                                      queue:(dispatch_queue_t)queue
                          completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNOCsWithClusterStateCache:attributeCacheContainer.realContainer
                                        endpoint:endpoint
                                           queue:queue
                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          completionHandler(static_cast<NSArray *>(value), error);
                                      }];
}

- (void)readAttributeFabricsWithParams:(MTRReadParams * _Nullable)params
                     completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFabricsWithParams:params
                              completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                  // Cast is safe because subclass does not add any selectors.
                                  completionHandler(static_cast<NSArray *>(value), error);
                              }];
}
- (void)subscribeAttributeFabricsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                          params:(MTRSubscribeParams * _Nullable)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                   reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFabricsWithParams:subscribeParams
                      subscriptionEstablished:subscriptionEstablishedHandler
                                reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                    // Cast is safe because subclass does not add any selectors.
                                    reportHandler(static_cast<NSArray *>(value), error);
                                }];
}
+ (void)readAttributeFabricsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                      endpoint:(NSNumber *)endpoint
                                         queue:(dispatch_queue_t)queue
                             completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFabricsWithClusterStateCache:attributeCacheContainer.realContainer
                                           endpoint:endpoint
                                              queue:queue
                                         completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             completionHandler(static_cast<NSArray *>(value), error);
                                         }];
}

- (void)readAttributeSupportedFabricsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeSupportedFabricsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)
    subscribeAttributeSupportedFabricsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeSupportedFabricsWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributeSupportedFabricsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSupportedFabricsWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeCommissionedFabricsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeCommissionedFabricsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeCommissionedFabricsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeCommissionedFabricsWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSNumber *>(value), error);
                                            }];
}
+ (void)readAttributeCommissionedFabricsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCommissionedFabricsWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}

- (void)readAttributeTrustedRootCertificatesWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    [self readAttributeTrustedRootCertificatesWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeTrustedRootCertificatesWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                                          params:(MTRSubscribeParams * _Nullable)params
                                         subscriptionEstablished:
                                             (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                   reportHandler:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeTrustedRootCertificatesWithParams:subscribeParams
                                      subscriptionEstablished:subscriptionEstablishedHandler
                                                reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    reportHandler(static_cast<NSArray *>(value), error);
                                                }];
}
+ (void)readAttributeTrustedRootCertificatesWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                             completionHandler:
                                                 (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeTrustedRootCertificatesWithClusterStateCache:attributeCacheContainer.realContainer
                                                           endpoint:endpoint
                                                              queue:queue
                                                         completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                             // Cast is safe because subclass does not add any selectors.
                                                             completionHandler(static_cast<NSArray *>(value), error);
                                                         }];
}

- (void)readAttributeCurrentFabricIndexWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentFabricIndexWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeCurrentFabricIndexWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:
                                        (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeCurrentFabricIndexWithParams:subscribeParams
                                 subscriptionEstablished:subscriptionEstablishedHandler
                                           reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               reportHandler(static_cast<NSNumber *>(value), error);
                                           }];
}
+ (void)readAttributeCurrentFabricIndexWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentFabricIndexWithClusterStateCache:attributeCacheContainer.realContainer
                                                      endpoint:endpoint
                                                         queue:queue
                                                    completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                        // Cast is safe because subclass does not add any selectors.
                                                        completionHandler(static_cast<NSNumber *>(value), error);
                                                    }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterGroupKeyManagement

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)keySetWriteWithParams:(MTRGroupKeyManagementClusterKeySetWriteParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            GroupKeyManagement::Commands::KeySetWrite::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.groupKeySet.groupKeySetID = params.groupKeySet.groupKeySetID.unsignedShortValue;
            request.groupKeySet.groupKeySecurityPolicy
                = static_cast<std::remove_reference_t<decltype(request.groupKeySet.groupKeySecurityPolicy)>>(
                    params.groupKeySet.groupKeySecurityPolicy.unsignedCharValue);
            if (params.groupKeySet.epochKey0 == nil) {
                request.groupKeySet.epochKey0.SetNull();
            } else {
                auto & nonNullValue_1 = request.groupKeySet.epochKey0.SetNonNull();
                nonNullValue_1 = [self asByteSpan:params.groupKeySet.epochKey0];
            }
            if (params.groupKeySet.epochStartTime0 == nil) {
                request.groupKeySet.epochStartTime0.SetNull();
            } else {
                auto & nonNullValue_1 = request.groupKeySet.epochStartTime0.SetNonNull();
                nonNullValue_1 = params.groupKeySet.epochStartTime0.unsignedLongLongValue;
            }
            if (params.groupKeySet.epochKey1 == nil) {
                request.groupKeySet.epochKey1.SetNull();
            } else {
                auto & nonNullValue_1 = request.groupKeySet.epochKey1.SetNonNull();
                nonNullValue_1 = [self asByteSpan:params.groupKeySet.epochKey1];
            }
            if (params.groupKeySet.epochStartTime1 == nil) {
                request.groupKeySet.epochStartTime1.SetNull();
            } else {
                auto & nonNullValue_1 = request.groupKeySet.epochStartTime1.SetNonNull();
                nonNullValue_1 = params.groupKeySet.epochStartTime1.unsignedLongLongValue;
            }
            if (params.groupKeySet.epochKey2 == nil) {
                request.groupKeySet.epochKey2.SetNull();
            } else {
                auto & nonNullValue_1 = request.groupKeySet.epochKey2.SetNonNull();
                nonNullValue_1 = [self asByteSpan:params.groupKeySet.epochKey2];
            }
            if (params.groupKeySet.epochStartTime2 == nil) {
                request.groupKeySet.epochStartTime2.SetNull();
            } else {
                auto & nonNullValue_1 = request.groupKeySet.epochStartTime2.SetNonNull();
                nonNullValue_1 = params.groupKeySet.epochStartTime2.unsignedLongLongValue;
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)keySetReadWithParams:(MTRGroupKeyManagementClusterKeySetReadParams *)params
                  completion:(void (^)(MTRGroupKeyManagementClusterKeySetReadResponseParams * _Nullable data,
                                 NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRGroupKeyManagementClusterKeySetReadResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            GroupKeyManagementClusterKeySetReadResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRGroupKeyManagementClusterKeySetReadResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            GroupKeyManagement::Commands::KeySetRead::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.groupKeySetID = params.groupKeySetID.unsignedShortValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)keySetRemoveWithParams:(MTRGroupKeyManagementClusterKeySetRemoveParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            GroupKeyManagement::Commands::KeySetRemove::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.groupKeySetID = params.groupKeySetID.unsignedShortValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)keySetReadAllIndicesWithParams:(MTRGroupKeyManagementClusterKeySetReadAllIndicesParams *)params
                            completion:(void (^)(MTRGroupKeyManagementClusterKeySetReadAllIndicesResponseParams * _Nullable data,
                                           NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRGroupKeyManagementClusterKeySetReadAllIndicesResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            GroupKeyManagementClusterKeySetReadAllIndicesResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRGroupKeyManagementClusterKeySetReadAllIndicesResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            GroupKeyManagement::Commands::KeySetReadAllIndices::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            {
                using ListType_0 = std::remove_reference_t<decltype(request.groupKeySetIDs)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (params.groupKeySetIDs.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(params.groupKeySetIDs.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < params.groupKeySetIDs.count; ++i_0) {
                        if (![params.groupKeySetIDs[i_0] isKindOfClass:[NSNumber class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (NSNumber *) params.groupKeySetIDs[i_0];
                        listHolder_0->mList[i_0] = element_0.unsignedShortValue;
                    }
                    request.groupKeySetIDs = ListType_0(listHolder_0->mList, params.groupKeySetIDs.count);
                } else {
                    request.groupKeySetIDs = ListType_0();
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeGroupKeyMapWithParams:(MTRReadParams * _Nullable)params
                                completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{ // Make a copy of params before we go async.
    params = [params copy];
    using TypeInfo = GroupKeyManagement::Attributes::GroupKeyMap::TypeInfo;
    return MTRReadAttribute<MTRGroupKeyManagementGroupKeyMapListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeGroupKeyMapWithValue:(NSArray * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeGroupKeyMapWithValue:(NSArray * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeGroupKeyMapWithValue:(NSArray * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                                completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = GroupKeyManagement::Attributes::GroupKeyMap::TypeInfo;
            TypeInfo::Type cppValue;
            {
                using ListType_0 = std::remove_reference_t<decltype(cppValue)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (value.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(value.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < value.count; ++i_0) {
                        if (![value[i_0] isKindOfClass:[MTRGroupKeyManagementClusterGroupKeyMapStruct class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (MTRGroupKeyManagementClusterGroupKeyMapStruct *) value[i_0];
                        listHolder_0->mList[i_0].groupId = element_0.groupId.unsignedShortValue;
                        listHolder_0->mList[i_0].groupKeySetID = element_0.groupKeySetID.unsignedShortValue;
                        listHolder_0->mList[i_0].fabricIndex = element_0.fabricIndex.unsignedCharValue;
                    }
                    cppValue = ListType_0(listHolder_0->mList, value.count);
                } else {
                    cppValue = ListType_0();
                }
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeGroupKeyMapWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = GroupKeyManagement::Attributes::GroupKeyMap::TypeInfo;
    MTRSubscribeAttribute<MTRGroupKeyManagementGroupKeyMapListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGroupKeyMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRGroupKeyManagementGroupKeyMapListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(GroupKeyManagementGroupKeyMapListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GroupKeyManagement::Attributes::GroupKeyMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGroupTableWithParams:(MTRReadParams * _Nullable)params
                               completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{ // Make a copy of params before we go async.
    params = [params copy];
    using TypeInfo = GroupKeyManagement::Attributes::GroupTable::TypeInfo;
    return MTRReadAttribute<MTRGroupKeyManagementGroupTableListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGroupTableWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = GroupKeyManagement::Attributes::GroupTable::TypeInfo;
    MTRSubscribeAttribute<MTRGroupKeyManagementGroupTableListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeGroupTableWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRGroupKeyManagementGroupTableListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(GroupKeyManagementGroupTableListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GroupKeyManagement::Attributes::GroupTable::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMaxGroupsPerFabricWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = GroupKeyManagement::Attributes::MaxGroupsPerFabric::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMaxGroupsPerFabricWithParams:(MTRSubscribeParams * _Nonnull)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = GroupKeyManagement::Attributes::MaxGroupsPerFabric::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMaxGroupsPerFabricWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                                  completion:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GroupKeyManagement::Attributes::MaxGroupsPerFabric::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMaxGroupKeysPerFabricWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = GroupKeyManagement::Attributes::MaxGroupKeysPerFabric::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMaxGroupKeysPerFabricWithParams:(MTRSubscribeParams * _Nonnull)params
                                  subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = GroupKeyManagement::Attributes::MaxGroupKeysPerFabric::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMaxGroupKeysPerFabricWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                                     completion:
                                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GroupKeyManagement::Attributes::MaxGroupKeysPerFabric::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = GroupKeyManagement::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRGroupKeyManagementGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = GroupKeyManagement::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRGroupKeyManagementGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRGroupKeyManagementGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(GroupKeyManagementGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GroupKeyManagement::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = GroupKeyManagement::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRGroupKeyManagementAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = GroupKeyManagement::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRGroupKeyManagementAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRGroupKeyManagementAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(GroupKeyManagementAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GroupKeyManagement::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = GroupKeyManagement::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRGroupKeyManagementEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = GroupKeyManagement::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRGroupKeyManagementEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRGroupKeyManagementEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(GroupKeyManagementEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GroupKeyManagement::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = GroupKeyManagement::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRGroupKeyManagementAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = GroupKeyManagement::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRGroupKeyManagementAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRGroupKeyManagementAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(GroupKeyManagementAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GroupKeyManagement::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = GroupKeyManagement::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = GroupKeyManagement::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GroupKeyManagement::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = GroupKeyManagement::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = GroupKeyManagement::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GroupKeyManagement::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterGroupKeyManagement (Deprecated)

- (void)keySetWriteWithParams:(MTRGroupKeyManagementClusterKeySetWriteParams *)params
            completionHandler:(MTRStatusCompletion)completionHandler
{
    [self keySetWriteWithParams:params completion:completionHandler];
}
- (void)keySetReadWithParams:(MTRGroupKeyManagementClusterKeySetReadParams *)params
           completionHandler:(void (^)(MTRGroupKeyManagementClusterKeySetReadResponseParams * _Nullable data,
                                 NSError * _Nullable error))completionHandler
{
    [self keySetReadWithParams:params
                    completion:^(MTRGroupKeyManagementClusterKeySetReadResponseParams * _Nullable data, NSError * _Nullable error) {
                        // Cast is safe because subclass does not add any selectors.
                        completionHandler(static_cast<MTRGroupKeyManagementClusterKeySetReadResponseParams *>(data), error);
                    }];
}
- (void)keySetRemoveWithParams:(MTRGroupKeyManagementClusterKeySetRemoveParams *)params
             completionHandler:(MTRStatusCompletion)completionHandler
{
    [self keySetRemoveWithParams:params completion:completionHandler];
}
- (void)keySetReadAllIndicesWithParams:(MTRGroupKeyManagementClusterKeySetReadAllIndicesParams *)params
                     completionHandler:(void (^)(MTRGroupKeyManagementClusterKeySetReadAllIndicesResponseParams * _Nullable data,
                                           NSError * _Nullable error))completionHandler
{
    [self keySetReadAllIndicesWithParams:params
                              completion:^(MTRGroupKeyManagementClusterKeySetReadAllIndicesResponseParams * _Nullable data,
                                  NSError * _Nullable error) {
                                  // Cast is safe because subclass does not add any selectors.
                                  completionHandler(
                                      static_cast<MTRGroupKeyManagementClusterKeySetReadAllIndicesResponseParams *>(data), error);
                              }];
}

- (void)readAttributeGroupKeyMapWithParams:(MTRReadParams * _Nullable)params
                         completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGroupKeyMapWithParams:params
                                  completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                      // Cast is safe because subclass does not add any selectors.
                                      completionHandler(static_cast<NSArray *>(value), error);
                                  }];
}
- (void)writeAttributeGroupKeyMapWithValue:(NSArray * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeGroupKeyMapWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeGroupKeyMapWithValue:(NSArray * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                         completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeGroupKeyMapWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeGroupKeyMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGroupKeyMapWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSArray *>(value), error);
                                    }];
}
+ (void)readAttributeGroupKeyMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGroupKeyMapWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSArray *>(value), error);
                                             }];
}

- (void)readAttributeGroupTableWithParams:(MTRReadParams * _Nullable)params
                        completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGroupTableWithParams:params
                                 completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                     // Cast is safe because subclass does not add any selectors.
                                     completionHandler(static_cast<NSArray *>(value), error);
                                 }];
}
- (void)subscribeAttributeGroupTableWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGroupTableWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSArray *>(value), error);
                                   }];
}
+ (void)readAttributeGroupTableWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGroupTableWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSArray *>(value), error);
                                            }];
}

- (void)readAttributeMaxGroupsPerFabricWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxGroupsPerFabricWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeMaxGroupsPerFabricWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:
                                        (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMaxGroupsPerFabricWithParams:subscribeParams
                                 subscriptionEstablished:subscriptionEstablishedHandler
                                           reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               reportHandler(static_cast<NSNumber *>(value), error);
                                           }];
}
+ (void)readAttributeMaxGroupsPerFabricWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxGroupsPerFabricWithClusterStateCache:attributeCacheContainer.realContainer
                                                      endpoint:endpoint
                                                         queue:queue
                                                    completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                        // Cast is safe because subclass does not add any selectors.
                                                        completionHandler(static_cast<NSNumber *>(value), error);
                                                    }];
}

- (void)readAttributeMaxGroupKeysPerFabricWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxGroupKeysPerFabricWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeMaxGroupKeysPerFabricWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMaxGroupKeysPerFabricWithParams:subscribeParams
                                    subscriptionEstablished:subscriptionEstablishedHandler
                                              reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  reportHandler(static_cast<NSNumber *>(value), error);
                                              }];
}
+ (void)readAttributeMaxGroupKeysPerFabricWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxGroupKeysPerFabricWithClusterStateCache:attributeCacheContainer.realContainer
                                                         endpoint:endpoint
                                                            queue:queue
                                                       completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                           // Cast is safe because subclass does not add any selectors.
                                                           completionHandler(static_cast<NSNumber *>(value), error);
                                                       }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterFixedLabel

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)readAttributeLabelListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FixedLabel::Attributes::LabelList::TypeInfo;
    return MTRReadAttribute<MTRFixedLabelLabelListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeLabelListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FixedLabel::Attributes::LabelList::TypeInfo;
    MTRSubscribeAttribute<MTRFixedLabelLabelListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeLabelListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRFixedLabelLabelListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(FixedLabelLabelListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FixedLabel::Attributes::LabelList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FixedLabel::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRFixedLabelGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FixedLabel::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRFixedLabelGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRFixedLabelGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(FixedLabelGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FixedLabel::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FixedLabel::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRFixedLabelAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FixedLabel::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRFixedLabelAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRFixedLabelAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(FixedLabelAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FixedLabel::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FixedLabel::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRFixedLabelEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FixedLabel::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRFixedLabelEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRFixedLabelEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(FixedLabelEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FixedLabel::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FixedLabel::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRFixedLabelAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FixedLabel::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRFixedLabelAttributeListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRFixedLabelAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(FixedLabelAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FixedLabel::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FixedLabel::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FixedLabel::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FixedLabel::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FixedLabel::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FixedLabel::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FixedLabel::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterFixedLabel (Deprecated)

- (void)readAttributeLabelListWithCompletionHandler:(void (^)(
                                                        NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLabelListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeLabelListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeLabelListWithParams:subscribeParams
                        subscriptionEstablished:subscriptionEstablishedHandler
                                  reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                      // Cast is safe because subclass does not add any selectors.
                                      reportHandler(static_cast<NSArray *>(value), error);
                                  }];
}
+ (void)readAttributeLabelListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLabelListWithClusterStateCache:attributeCacheContainer.realContainer
                                             endpoint:endpoint
                                                queue:queue
                                           completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               completionHandler(static_cast<NSArray *>(value), error);
                                           }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterUserLabel

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)readAttributeLabelListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UserLabel::Attributes::LabelList::TypeInfo;
    return MTRReadAttribute<MTRUserLabelLabelListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeLabelListWithValue:(NSArray * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeLabelListWithValue:(NSArray * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeLabelListWithValue:(NSArray * _Nonnull)value
                                  params:(MTRWriteParams * _Nullable)params
                              completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UserLabel::Attributes::LabelList::TypeInfo;
            TypeInfo::Type cppValue;
            {
                using ListType_0 = std::remove_reference_t<decltype(cppValue)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (value.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(value.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < value.count; ++i_0) {
                        if (![value[i_0] isKindOfClass:[MTRUserLabelClusterLabelStruct class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (MTRUserLabelClusterLabelStruct *) value[i_0];
                        listHolder_0->mList[i_0].label = [self asCharSpan:element_0.label];
                        listHolder_0->mList[i_0].value = [self asCharSpan:element_0.value];
                    }
                    cppValue = ListType_0(listHolder_0->mList, value.count);
                } else {
                    cppValue = ListType_0();
                }
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeLabelListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UserLabel::Attributes::LabelList::TypeInfo;
    MTRSubscribeAttribute<MTRUserLabelLabelListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeLabelListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRUserLabelLabelListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(UserLabelLabelListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UserLabel::Attributes::LabelList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UserLabel::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRUserLabelGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UserLabel::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRUserLabelGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRUserLabelGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(UserLabelGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UserLabel::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UserLabel::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRUserLabelAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UserLabel::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRUserLabelAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRUserLabelAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(UserLabelAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UserLabel::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UserLabel::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRUserLabelEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UserLabel::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRUserLabelEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRUserLabelEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(UserLabelEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UserLabel::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UserLabel::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRUserLabelAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UserLabel::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRUserLabelAttributeListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRUserLabelAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(UserLabelAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UserLabel::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UserLabel::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UserLabel::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UserLabel::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UserLabel::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UserLabel::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UserLabel::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterUserLabel (Deprecated)

- (void)readAttributeLabelListWithCompletionHandler:(void (^)(
                                                        NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLabelListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)writeAttributeLabelListWithValue:(NSArray * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeLabelListWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeLabelListWithValue:(NSArray * _Nonnull)value
                                  params:(MTRWriteParams * _Nullable)params
                       completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeLabelListWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeLabelListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeLabelListWithParams:subscribeParams
                        subscriptionEstablished:subscriptionEstablishedHandler
                                  reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                      // Cast is safe because subclass does not add any selectors.
                                      reportHandler(static_cast<NSArray *>(value), error);
                                  }];
}
+ (void)readAttributeLabelListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLabelListWithClusterStateCache:attributeCacheContainer.realContainer
                                             endpoint:endpoint
                                                queue:queue
                                           completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               completionHandler(static_cast<NSArray *>(value), error);
                                           }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterBooleanState

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)readAttributeStateValueWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BooleanState::Attributes::StateValue::TypeInfo;
    return MTRReadAttribute<MTRBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeStateValueWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BooleanState::Attributes::StateValue::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeStateValueWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BooleanState::Attributes::StateValue::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BooleanState::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRBooleanStateGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BooleanState::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanStateGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanStateGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(BooleanStateGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BooleanState::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BooleanState::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRBooleanStateAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BooleanState::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanStateAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanStateAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(BooleanStateAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BooleanState::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BooleanState::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRBooleanStateEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BooleanState::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanStateEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanStateEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanStateEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BooleanState::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BooleanState::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRBooleanStateAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BooleanState::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanStateAttributeListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanStateAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(BooleanStateAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BooleanState::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BooleanState::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BooleanState::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BooleanState::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BooleanState::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BooleanState::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BooleanState::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterBooleanState (Deprecated)

- (void)readAttributeStateValueWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeStateValueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeStateValueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeStateValueWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeStateValueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeStateValueWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterModeSelect

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)changeToModeWithParams:(MTRModeSelectClusterChangeToModeParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            ModeSelect::Commands::ChangeToMode::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.newMode = params.newMode.unsignedCharValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeDescriptionWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ModeSelect::Attributes::Description::TypeInfo;
    return MTRReadAttribute<MTRCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeDescriptionWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ModeSelect::Attributes::Description::TypeInfo;
    MTRSubscribeAttribute<MTRCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeDescriptionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(CharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ModeSelect::Attributes::Description::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeStandardNamespaceWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ModeSelect::Attributes::StandardNamespace::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeStandardNamespaceWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ModeSelect::Attributes::StandardNamespace::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeStandardNamespaceWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ModeSelect::Attributes::StandardNamespace::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSupportedModesWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ModeSelect::Attributes::SupportedModes::TypeInfo;
    return MTRReadAttribute<MTRModeSelectSupportedModesListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeSupportedModesWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ModeSelect::Attributes::SupportedModes::TypeInfo;
    MTRSubscribeAttribute<MTRModeSelectSupportedModesListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeSupportedModesWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRModeSelectSupportedModesListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ModeSelectSupportedModesListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ModeSelect::Attributes::SupportedModes::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCurrentModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ModeSelect::Attributes::CurrentMode::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeCurrentModeWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ModeSelect::Attributes::CurrentMode::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeCurrentModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ModeSelect::Attributes::CurrentMode::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeStartUpModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ModeSelect::Attributes::StartUpMode::TypeInfo;
    return MTRReadAttribute<MTRNullableInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeStartUpModeWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeStartUpModeWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeStartUpModeWithValue:(NSNumber * _Nullable)value
                                    params:(MTRWriteParams * _Nullable)params
                                completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ModeSelect::Attributes::StartUpMode::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedCharValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeStartUpModeWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ModeSelect::Attributes::StartUpMode::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeStartUpModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ModeSelect::Attributes::StartUpMode::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeOnModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ModeSelect::Attributes::OnMode::TypeInfo;
    return MTRReadAttribute<MTRNullableInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeOnModeWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeOnModeWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeOnModeWithValue:(NSNumber * _Nullable)value
                               params:(MTRWriteParams * _Nullable)params
                           completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ModeSelect::Attributes::OnMode::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedCharValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeOnModeWithParams:(MTRSubscribeParams * _Nonnull)params
                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                             reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ModeSelect::Attributes::OnMode::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeOnModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                                      completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ModeSelect::Attributes::OnMode::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ModeSelect::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRModeSelectGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ModeSelect::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRModeSelectGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRModeSelectGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ModeSelectGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ModeSelect::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ModeSelect::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRModeSelectAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ModeSelect::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRModeSelectAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRModeSelectAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ModeSelectAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ModeSelect::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ModeSelect::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRModeSelectEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ModeSelect::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRModeSelectEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRModeSelectEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(ModeSelectEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ModeSelect::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ModeSelect::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRModeSelectAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ModeSelect::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRModeSelectAttributeListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRModeSelectAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ModeSelectAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ModeSelect::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ModeSelect::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ModeSelect::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ModeSelect::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ModeSelect::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ModeSelect::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ModeSelect::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterModeSelect (Deprecated)

- (void)changeToModeWithParams:(MTRModeSelectClusterChangeToModeParams *)params
             completionHandler:(MTRStatusCompletion)completionHandler
{
    [self changeToModeWithParams:params completion:completionHandler];
}

- (void)readAttributeDescriptionWithCompletionHandler:(void (^)(
                                                          NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDescriptionWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)subscribeAttributeDescriptionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeDescriptionWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSString *>(value), error);
                                    }];
}
+ (void)readAttributeDescriptionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDescriptionWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSString *>(value), error);
                                             }];
}

- (void)readAttributeStandardNamespaceWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeStandardNamespaceWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeStandardNamespaceWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeStandardNamespaceWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSNumber *>(value), error);
                                          }];
}
+ (void)readAttributeStandardNamespaceWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeStandardNamespaceWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}

- (void)readAttributeSupportedModesWithCompletionHandler:(void (^)(
                                                             NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSupportedModesWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeSupportedModesWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeSupportedModesWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSArray *>(value), error);
                                       }];
}
+ (void)readAttributeSupportedModesWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSupportedModesWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSArray *>(value), error);
                                                }];
}

- (void)readAttributeCurrentModeWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeCurrentModeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeCurrentModeWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSNumber *>(value), error);
                                    }];
}
+ (void)readAttributeCurrentModeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentModeWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                             }];
}

- (void)readAttributeStartUpModeWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeStartUpModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeStartUpModeWithValue:(NSNumber * _Nullable)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeStartUpModeWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeStartUpModeWithValue:(NSNumber * _Nullable)value
                                    params:(MTRWriteParams * _Nullable)params
                         completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeStartUpModeWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeStartUpModeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeStartUpModeWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSNumber *>(value), error);
                                    }];
}
+ (void)readAttributeStartUpModeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeStartUpModeWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                             }];
}

- (void)readAttributeOnModeWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOnModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeOnModeWithValue:(NSNumber * _Nullable)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeOnModeWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeOnModeWithValue:(NSNumber * _Nullable)value
                               params:(MTRWriteParams * _Nullable)params
                    completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeOnModeWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeOnModeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeOnModeWithParams:subscribeParams
                     subscriptionEstablished:subscriptionEstablishedHandler
                               reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                   // Cast is safe because subclass does not add any selectors.
                                   reportHandler(static_cast<NSNumber *>(value), error);
                               }];
}
+ (void)readAttributeOnModeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOnModeWithClusterStateCache:attributeCacheContainer.realContainer
                                          endpoint:endpoint
                                             queue:queue
                                        completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            completionHandler(static_cast<NSNumber *>(value), error);
                                        }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterTemperatureControl

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)setTemperatureWithParams:(MTRTemperatureControlClusterSetTemperatureParams * _Nullable)params
                      completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            TemperatureControl::Commands::SetTemperature::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            if (params != nil) {
                if (params.targetTemperature != nil) {
                    auto & definedValue_0 = request.targetTemperature.Emplace();
                    definedValue_0 = params.targetTemperature.shortValue;
                }
                if (params.targetTemperatureLevel != nil) {
                    auto & definedValue_0 = request.targetTemperatureLevel.Emplace();
                    definedValue_0 = params.targetTemperatureLevel.unsignedCharValue;
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeTemperatureSetpointWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TemperatureControl::Attributes::TemperatureSetpoint::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeTemperatureSetpointWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TemperatureControl::Attributes::TemperatureSetpoint::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeTemperatureSetpointWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TemperatureControl::Attributes::TemperatureSetpoint::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMinTemperatureWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TemperatureControl::Attributes::MinTemperature::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMinTemperatureWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TemperatureControl::Attributes::MinTemperature::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMinTemperatureWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TemperatureControl::Attributes::MinTemperature::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMaxTemperatureWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TemperatureControl::Attributes::MaxTemperature::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMaxTemperatureWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TemperatureControl::Attributes::MaxTemperature::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMaxTemperatureWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TemperatureControl::Attributes::MaxTemperature::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeStepWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TemperatureControl::Attributes::Step::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeStepWithParams:(MTRSubscribeParams * _Nonnull)params
                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                           reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TemperatureControl::Attributes::Step::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeStepWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                      endpoint:(NSNumber *)endpoint
                                         queue:(dispatch_queue_t)queue
                                    completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TemperatureControl::Attributes::Step::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCurrentTemperatureLevelIndexWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TemperatureControl::Attributes::CurrentTemperatureLevelIndex::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeCurrentTemperatureLevelIndexWithParams:(MTRSubscribeParams * _Nonnull)params
                                         subscriptionEstablished:
                                             (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                   reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))reportHandler
{
    using TypeInfo = TemperatureControl::Attributes::CurrentTemperatureLevelIndex::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeCurrentTemperatureLevelIndexWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                              endpoint:(NSNumber *)endpoint
                                                                 queue:(dispatch_queue_t)queue
                                                            completion:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TemperatureControl::Attributes::CurrentTemperatureLevelIndex::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSupportedTemperatureLevelsWithCompletion:(void (^)(
                                                                  NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TemperatureControl::Attributes::SupportedTemperatureLevels::TypeInfo;
    return MTRReadAttribute<MTRTemperatureControlSupportedTemperatureLevelsListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeSupportedTemperatureLevelsWithParams:(MTRSubscribeParams * _Nonnull)params
                                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                 reportHandler:
                                                     (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TemperatureControl::Attributes::SupportedTemperatureLevels::TypeInfo;
    MTRSubscribeAttribute<MTRTemperatureControlSupportedTemperatureLevelsListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeSupportedTemperatureLevelsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                            endpoint:(NSNumber *)endpoint
                                                               queue:(dispatch_queue_t)queue
                                                          completion:(void (^)(NSArray * _Nullable value,
                                                                         NSError * _Nullable error))completion
{
    auto * bridge = new MTRTemperatureControlSupportedTemperatureLevelsListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(TemperatureControlSupportedTemperatureLevelsListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TemperatureControl::Attributes::SupportedTemperatureLevels::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TemperatureControl::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRTemperatureControlGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TemperatureControl::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRTemperatureControlGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRTemperatureControlGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(TemperatureControlGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TemperatureControl::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TemperatureControl::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRTemperatureControlAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TemperatureControl::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRTemperatureControlAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRTemperatureControlAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(TemperatureControlAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TemperatureControl::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TemperatureControl::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRTemperatureControlEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TemperatureControl::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRTemperatureControlEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRTemperatureControlEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(TemperatureControlEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TemperatureControl::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TemperatureControl::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRTemperatureControlAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TemperatureControl::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRTemperatureControlAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRTemperatureControlAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(TemperatureControlAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TemperatureControl::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TemperatureControl::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TemperatureControl::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TemperatureControl::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TemperatureControl::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TemperatureControl::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TemperatureControl::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterRefrigeratorAlarm

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)resetWithParams:(MTRRefrigeratorAlarmClusterResetParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            RefrigeratorAlarm::Commands::Reset::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.alarms = static_cast<std::remove_reference_t<decltype(request.alarms)>>(params.alarms.unsignedIntValue);
            if (params.mask != nil) {
                auto & definedValue_0 = request.mask.Emplace();
                definedValue_0 = static_cast<std::remove_reference_t<decltype(definedValue_0)>>(params.mask.unsignedIntValue);
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeMaskWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = RefrigeratorAlarm::Attributes::Mask::TypeInfo;
    return MTRReadAttribute<MTRRefrigeratorAlarmMaskAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeMaskWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeMaskWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeMaskWithValue:(NSNumber * _Nonnull)value
                             params:(MTRWriteParams * _Nullable)params
                         completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = RefrigeratorAlarm::Attributes::Mask::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = static_cast<std::remove_reference_t<decltype(cppValue)>>(value.unsignedIntValue);

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeMaskWithParams:(MTRSubscribeParams * _Nonnull)params
                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                           reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = RefrigeratorAlarm::Attributes::Mask::TypeInfo;
    MTRSubscribeAttribute<MTRRefrigeratorAlarmMaskAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMaskWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                      endpoint:(NSNumber *)endpoint
                                         queue:(dispatch_queue_t)queue
                                    completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRRefrigeratorAlarmMaskAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(RefrigeratorAlarmMaskAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = RefrigeratorAlarm::Attributes::Mask::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeLatchWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = RefrigeratorAlarm::Attributes::Latch::TypeInfo;
    return MTRReadAttribute<MTRRefrigeratorAlarmLatchAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeLatchWithParams:(MTRSubscribeParams * _Nonnull)params
                  subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                            reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = RefrigeratorAlarm::Attributes::Latch::TypeInfo;
    MTRSubscribeAttribute<MTRRefrigeratorAlarmLatchAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeLatchWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                                     completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRRefrigeratorAlarmLatchAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(RefrigeratorAlarmLatchAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = RefrigeratorAlarm::Attributes::Latch::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeStateWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = RefrigeratorAlarm::Attributes::State::TypeInfo;
    return MTRReadAttribute<MTRRefrigeratorAlarmStateAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeStateWithParams:(MTRSubscribeParams * _Nonnull)params
                  subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                            reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = RefrigeratorAlarm::Attributes::State::TypeInfo;
    MTRSubscribeAttribute<MTRRefrigeratorAlarmStateAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeStateWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                                     completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRRefrigeratorAlarmStateAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(RefrigeratorAlarmStateAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = RefrigeratorAlarm::Attributes::State::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = RefrigeratorAlarm::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRRefrigeratorAlarmGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = RefrigeratorAlarm::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRRefrigeratorAlarmGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRRefrigeratorAlarmGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(RefrigeratorAlarmGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = RefrigeratorAlarm::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = RefrigeratorAlarm::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRRefrigeratorAlarmAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = RefrigeratorAlarm::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRRefrigeratorAlarmAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRRefrigeratorAlarmAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(RefrigeratorAlarmAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = RefrigeratorAlarm::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = RefrigeratorAlarm::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRRefrigeratorAlarmEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = RefrigeratorAlarm::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRRefrigeratorAlarmEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRRefrigeratorAlarmEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(RefrigeratorAlarmEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = RefrigeratorAlarm::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = RefrigeratorAlarm::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRRefrigeratorAlarmAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = RefrigeratorAlarm::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRRefrigeratorAlarmAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRRefrigeratorAlarmAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(RefrigeratorAlarmAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = RefrigeratorAlarm::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = RefrigeratorAlarm::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = RefrigeratorAlarm::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = RefrigeratorAlarm::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = RefrigeratorAlarm::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = RefrigeratorAlarm::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = RefrigeratorAlarm::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterAirQuality

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)readAttributeAirQualityWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = AirQuality::Attributes::AirQuality::TypeInfo;
    return MTRReadAttribute<MTRAirQualityClusterAirQualityEnumAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAirQualityWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = AirQuality::Attributes::AirQuality::TypeInfo;
    MTRSubscribeAttribute<MTRAirQualityClusterAirQualityEnumAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAirQualityWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRAirQualityClusterAirQualityEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(AirQualityClusterAirQualityEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AirQuality::Attributes::AirQuality::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = AirQuality::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRAirQualityGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = AirQuality::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRAirQualityGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRAirQualityGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(AirQualityGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AirQuality::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = AirQuality::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRAirQualityAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = AirQuality::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRAirQualityAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRAirQualityAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(AirQualityAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AirQuality::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = AirQuality::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRAirQualityEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = AirQuality::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRAirQualityEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRAirQualityEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(AirQualityEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AirQuality::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = AirQuality::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRAirQualityAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = AirQuality::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRAirQualityAttributeListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRAirQualityAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(AirQualityAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AirQuality::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = AirQuality::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = AirQuality::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AirQuality::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = AirQuality::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = AirQuality::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AirQuality::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterSmokeCOAlarm

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)selfTestRequestWithCompletion:(MTRStatusCompletion)completion
{
    [self selfTestRequestWithParams:nil completion:completion];
}
- (void)selfTestRequestWithParams:(MTRSmokeCOAlarmClusterSelfTestRequestParams * _Nullable)params
                       completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            SmokeCoAlarm::Commands::SelfTestRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeExpressedStateWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = SmokeCoAlarm::Attributes::ExpressedState::TypeInfo;
    return MTRReadAttribute<MTRSmokeCOAlarmClusterExpressedStateEnumAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeExpressedStateWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = SmokeCoAlarm::Attributes::ExpressedState::TypeInfo;
    MTRSubscribeAttribute<MTRSmokeCOAlarmClusterExpressedStateEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeExpressedStateWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRSmokeCOAlarmClusterExpressedStateEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(SmokeCOAlarmClusterExpressedStateEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = SmokeCoAlarm::Attributes::ExpressedState::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSmokeStateWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = SmokeCoAlarm::Attributes::SmokeState::TypeInfo;
    return MTRReadAttribute<MTRSmokeCOAlarmClusterAlarmStateEnumAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeSmokeStateWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = SmokeCoAlarm::Attributes::SmokeState::TypeInfo;
    MTRSubscribeAttribute<MTRSmokeCOAlarmClusterAlarmStateEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeSmokeStateWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRSmokeCOAlarmClusterAlarmStateEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(SmokeCOAlarmClusterAlarmStateEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = SmokeCoAlarm::Attributes::SmokeState::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCOStateWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = SmokeCoAlarm::Attributes::COState::TypeInfo;
    return MTRReadAttribute<MTRSmokeCOAlarmClusterAlarmStateEnumAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeCOStateWithParams:(MTRSubscribeParams * _Nonnull)params
                    subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                              reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = SmokeCoAlarm::Attributes::COState::TypeInfo;
    MTRSubscribeAttribute<MTRSmokeCOAlarmClusterAlarmStateEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeCOStateWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                       completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRSmokeCOAlarmClusterAlarmStateEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(SmokeCOAlarmClusterAlarmStateEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = SmokeCoAlarm::Attributes::COState::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBatteryAlertWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = SmokeCoAlarm::Attributes::BatteryAlert::TypeInfo;
    return MTRReadAttribute<MTRSmokeCOAlarmClusterAlarmStateEnumAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeBatteryAlertWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = SmokeCoAlarm::Attributes::BatteryAlert::TypeInfo;
    MTRSubscribeAttribute<MTRSmokeCOAlarmClusterAlarmStateEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeBatteryAlertWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRSmokeCOAlarmClusterAlarmStateEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(SmokeCOAlarmClusterAlarmStateEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = SmokeCoAlarm::Attributes::BatteryAlert::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeDeviceMutedWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = SmokeCoAlarm::Attributes::DeviceMuted::TypeInfo;
    return MTRReadAttribute<MTRSmokeCOAlarmClusterMuteStateEnumAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeDeviceMutedWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = SmokeCoAlarm::Attributes::DeviceMuted::TypeInfo;
    MTRSubscribeAttribute<MTRSmokeCOAlarmClusterMuteStateEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeDeviceMutedWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRSmokeCOAlarmClusterMuteStateEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(SmokeCOAlarmClusterMuteStateEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = SmokeCoAlarm::Attributes::DeviceMuted::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeTestInProgressWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = SmokeCoAlarm::Attributes::TestInProgress::TypeInfo;
    return MTRReadAttribute<MTRBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeTestInProgressWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = SmokeCoAlarm::Attributes::TestInProgress::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeTestInProgressWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = SmokeCoAlarm::Attributes::TestInProgress::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeHardwareFaultAlertWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = SmokeCoAlarm::Attributes::HardwareFaultAlert::TypeInfo;
    return MTRReadAttribute<MTRBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeHardwareFaultAlertWithParams:(MTRSubscribeParams * _Nonnull)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = SmokeCoAlarm::Attributes::HardwareFaultAlert::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeHardwareFaultAlertWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                                  completion:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = SmokeCoAlarm::Attributes::HardwareFaultAlert::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEndOfServiceAlertWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = SmokeCoAlarm::Attributes::EndOfServiceAlert::TypeInfo;
    return MTRReadAttribute<MTRSmokeCOAlarmClusterEndOfServiceEnumAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEndOfServiceAlertWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = SmokeCoAlarm::Attributes::EndOfServiceAlert::TypeInfo;
    MTRSubscribeAttribute<MTRSmokeCOAlarmClusterEndOfServiceEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeEndOfServiceAlertWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRSmokeCOAlarmClusterEndOfServiceEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(SmokeCOAlarmClusterEndOfServiceEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = SmokeCoAlarm::Attributes::EndOfServiceAlert::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeInterconnectSmokeAlarmWithCompletion:(void (^)(
                                                              NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = SmokeCoAlarm::Attributes::InterconnectSmokeAlarm::TypeInfo;
    return MTRReadAttribute<MTRSmokeCOAlarmClusterAlarmStateEnumAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeInterconnectSmokeAlarmWithParams:(MTRSubscribeParams * _Nonnull)params
                                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = SmokeCoAlarm::Attributes::InterconnectSmokeAlarm::TypeInfo;
    MTRSubscribeAttribute<MTRSmokeCOAlarmClusterAlarmStateEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeInterconnectSmokeAlarmWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                                      completion:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completion
{
    auto * bridge = new MTRSmokeCOAlarmClusterAlarmStateEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(SmokeCOAlarmClusterAlarmStateEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = SmokeCoAlarm::Attributes::InterconnectSmokeAlarm::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeInterconnectCOAlarmWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = SmokeCoAlarm::Attributes::InterconnectCOAlarm::TypeInfo;
    return MTRReadAttribute<MTRSmokeCOAlarmClusterAlarmStateEnumAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeInterconnectCOAlarmWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = SmokeCoAlarm::Attributes::InterconnectCOAlarm::TypeInfo;
    MTRSubscribeAttribute<MTRSmokeCOAlarmClusterAlarmStateEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeInterconnectCOAlarmWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRSmokeCOAlarmClusterAlarmStateEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(SmokeCOAlarmClusterAlarmStateEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = SmokeCoAlarm::Attributes::InterconnectCOAlarm::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeContaminationStateWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = SmokeCoAlarm::Attributes::ContaminationState::TypeInfo;
    return MTRReadAttribute<MTRSmokeCOAlarmClusterContaminationStateEnumAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeContaminationStateWithParams:(MTRSubscribeParams * _Nonnull)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = SmokeCoAlarm::Attributes::ContaminationState::TypeInfo;
    MTRSubscribeAttribute<MTRSmokeCOAlarmClusterContaminationStateEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeContaminationStateWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                                  completion:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRSmokeCOAlarmClusterContaminationStateEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(SmokeCOAlarmClusterContaminationStateEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = SmokeCoAlarm::Attributes::ContaminationState::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSensitivityLevelWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = SmokeCoAlarm::Attributes::SensitivityLevel::TypeInfo;
    return MTRReadAttribute<MTRSmokeCOAlarmClusterSensitivityEnumAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeSensitivityLevelWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeSensitivityLevelWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeSensitivityLevelWithValue:(NSNumber * _Nonnull)value
                                         params:(MTRWriteParams * _Nullable)params
                                     completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = SmokeCoAlarm::Attributes::SensitivityLevel::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = static_cast<std::remove_reference_t<decltype(cppValue)>>(value.unsignedCharValue);

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeSensitivityLevelWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = SmokeCoAlarm::Attributes::SensitivityLevel::TypeInfo;
    MTRSubscribeAttribute<MTRSmokeCOAlarmClusterSensitivityEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeSensitivityLevelWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRSmokeCOAlarmClusterSensitivityEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(SmokeCOAlarmClusterSensitivityEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = SmokeCoAlarm::Attributes::SensitivityLevel::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = SmokeCoAlarm::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRSmokeCOAlarmGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = SmokeCoAlarm::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRSmokeCOAlarmGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRSmokeCOAlarmGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(SmokeCOAlarmGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = SmokeCoAlarm::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = SmokeCoAlarm::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRSmokeCOAlarmAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = SmokeCoAlarm::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRSmokeCOAlarmAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRSmokeCOAlarmAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(SmokeCOAlarmAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = SmokeCoAlarm::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = SmokeCoAlarm::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRSmokeCOAlarmEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = SmokeCoAlarm::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRSmokeCOAlarmEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRSmokeCOAlarmEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(SmokeCOAlarmEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = SmokeCoAlarm::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = SmokeCoAlarm::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRSmokeCOAlarmAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = SmokeCoAlarm::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRSmokeCOAlarmAttributeListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRSmokeCOAlarmAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(SmokeCOAlarmAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = SmokeCoAlarm::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = SmokeCoAlarm::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = SmokeCoAlarm::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = SmokeCoAlarm::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = SmokeCoAlarm::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = SmokeCoAlarm::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = SmokeCoAlarm::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterHEPAFilterMonitoring

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)resetConditionWithCompletion:(MTRStatusCompletion)completion
{
    [self resetConditionWithParams:nil completion:completion];
}
- (void)resetConditionWithParams:(MTRHEPAFilterMonitoringClusterResetConditionParams * _Nullable)params
                      completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            HepaFilterMonitoring::Commands::ResetCondition::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeConditionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = HepaFilterMonitoring::Attributes::Condition::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeConditionWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = HepaFilterMonitoring::Attributes::Condition::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeConditionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = HepaFilterMonitoring::Attributes::Condition::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeDegradationDirectionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = HepaFilterMonitoring::Attributes::DegradationDirection::TypeInfo;
    return MTRReadAttribute<MTRHEPAFilterMonitoringClusterDegradationDirectionEnumAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeDegradationDirectionWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = HepaFilterMonitoring::Attributes::DegradationDirection::TypeInfo;
    MTRSubscribeAttribute<MTRHEPAFilterMonitoringClusterDegradationDirectionEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeDegradationDirectionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRHEPAFilterMonitoringClusterDegradationDirectionEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(HEPAFilterMonitoringClusterDegradationDirectionEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = HepaFilterMonitoring::Attributes::DegradationDirection::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeChangeIndicationWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = HepaFilterMonitoring::Attributes::ChangeIndication::TypeInfo;
    return MTRReadAttribute<MTRHEPAFilterMonitoringClusterChangeIndicationEnumAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeChangeIndicationWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = HepaFilterMonitoring::Attributes::ChangeIndication::TypeInfo;
    MTRSubscribeAttribute<MTRHEPAFilterMonitoringClusterChangeIndicationEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeChangeIndicationWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRHEPAFilterMonitoringClusterChangeIndicationEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(HEPAFilterMonitoringClusterChangeIndicationEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = HepaFilterMonitoring::Attributes::ChangeIndication::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeInPlaceIndicatorWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = HepaFilterMonitoring::Attributes::InPlaceIndicator::TypeInfo;
    return MTRReadAttribute<MTRBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeInPlaceIndicatorWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = HepaFilterMonitoring::Attributes::InPlaceIndicator::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeInPlaceIndicatorWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = HepaFilterMonitoring::Attributes::InPlaceIndicator::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = HepaFilterMonitoring::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRHEPAFilterMonitoringGeneratedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = HepaFilterMonitoring::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRHEPAFilterMonitoringGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRHEPAFilterMonitoringGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(HEPAFilterMonitoringGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = HepaFilterMonitoring::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = HepaFilterMonitoring::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRHEPAFilterMonitoringAcceptedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = HepaFilterMonitoring::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRHEPAFilterMonitoringAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRHEPAFilterMonitoringAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(HEPAFilterMonitoringAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = HepaFilterMonitoring::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = HepaFilterMonitoring::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRHEPAFilterMonitoringEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = HepaFilterMonitoring::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRHEPAFilterMonitoringEventListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRHEPAFilterMonitoringEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(HEPAFilterMonitoringEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = HepaFilterMonitoring::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = HepaFilterMonitoring::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRHEPAFilterMonitoringAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = HepaFilterMonitoring::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRHEPAFilterMonitoringAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRHEPAFilterMonitoringAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(HEPAFilterMonitoringAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = HepaFilterMonitoring::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = HepaFilterMonitoring::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = HepaFilterMonitoring::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = HepaFilterMonitoring::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = HepaFilterMonitoring::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = HepaFilterMonitoring::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = HepaFilterMonitoring::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterActivatedCarbonFilterMonitoring

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)resetConditionWithCompletion:(MTRStatusCompletion)completion
{
    [self resetConditionWithParams:nil completion:completion];
}
- (void)resetConditionWithParams:(MTRActivatedCarbonFilterMonitoringClusterResetConditionParams * _Nullable)params
                      completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            ActivatedCarbonFilterMonitoring::Commands::ResetCondition::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeConditionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ActivatedCarbonFilterMonitoring::Attributes::Condition::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeConditionWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ActivatedCarbonFilterMonitoring::Attributes::Condition::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeConditionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ActivatedCarbonFilterMonitoring::Attributes::Condition::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeDegradationDirectionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ActivatedCarbonFilterMonitoring::Attributes::DegradationDirection::TypeInfo;
    return MTRReadAttribute<MTRActivatedCarbonFilterMonitoringClusterDegradationDirectionEnumAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeDegradationDirectionWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ActivatedCarbonFilterMonitoring::Attributes::DegradationDirection::TypeInfo;
    MTRSubscribeAttribute<MTRActivatedCarbonFilterMonitoringClusterDegradationDirectionEnumAttributeCallbackSubscriptionBridge,
        NSNumber, TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device,
        self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeDegradationDirectionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRActivatedCarbonFilterMonitoringClusterDegradationDirectionEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ActivatedCarbonFilterMonitoringClusterDegradationDirectionEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ActivatedCarbonFilterMonitoring::Attributes::DegradationDirection::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeChangeIndicationWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ActivatedCarbonFilterMonitoring::Attributes::ChangeIndication::TypeInfo;
    return MTRReadAttribute<MTRActivatedCarbonFilterMonitoringClusterChangeIndicationEnumAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeChangeIndicationWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ActivatedCarbonFilterMonitoring::Attributes::ChangeIndication::TypeInfo;
    MTRSubscribeAttribute<MTRActivatedCarbonFilterMonitoringClusterChangeIndicationEnumAttributeCallbackSubscriptionBridge,
        NSNumber, TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device,
        self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeChangeIndicationWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRActivatedCarbonFilterMonitoringClusterChangeIndicationEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ActivatedCarbonFilterMonitoringClusterChangeIndicationEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ActivatedCarbonFilterMonitoring::Attributes::ChangeIndication::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeInPlaceIndicatorWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ActivatedCarbonFilterMonitoring::Attributes::InPlaceIndicator::TypeInfo;
    return MTRReadAttribute<MTRBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeInPlaceIndicatorWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ActivatedCarbonFilterMonitoring::Attributes::InPlaceIndicator::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeInPlaceIndicatorWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ActivatedCarbonFilterMonitoring::Attributes::InPlaceIndicator::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ActivatedCarbonFilterMonitoring::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRActivatedCarbonFilterMonitoringGeneratedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ActivatedCarbonFilterMonitoring::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRActivatedCarbonFilterMonitoringGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRActivatedCarbonFilterMonitoringGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ActivatedCarbonFilterMonitoringGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ActivatedCarbonFilterMonitoring::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ActivatedCarbonFilterMonitoring::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRActivatedCarbonFilterMonitoringAcceptedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ActivatedCarbonFilterMonitoring::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRActivatedCarbonFilterMonitoringAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRActivatedCarbonFilterMonitoringAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ActivatedCarbonFilterMonitoringAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ActivatedCarbonFilterMonitoring::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ActivatedCarbonFilterMonitoring::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRActivatedCarbonFilterMonitoringEventListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ActivatedCarbonFilterMonitoring::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRActivatedCarbonFilterMonitoringEventListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRActivatedCarbonFilterMonitoringEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ActivatedCarbonFilterMonitoringEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ActivatedCarbonFilterMonitoring::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ActivatedCarbonFilterMonitoring::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRActivatedCarbonFilterMonitoringAttributeListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ActivatedCarbonFilterMonitoring::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRActivatedCarbonFilterMonitoringAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRActivatedCarbonFilterMonitoringAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ActivatedCarbonFilterMonitoringAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ActivatedCarbonFilterMonitoring::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ActivatedCarbonFilterMonitoring::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ActivatedCarbonFilterMonitoring::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ActivatedCarbonFilterMonitoring::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ActivatedCarbonFilterMonitoring::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ActivatedCarbonFilterMonitoring::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ActivatedCarbonFilterMonitoring::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterCeramicFilterMonitoring

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)resetConditionWithCompletion:(MTRStatusCompletion)completion
{
    [self resetConditionWithParams:nil completion:completion];
}
- (void)resetConditionWithParams:(MTRCeramicFilterMonitoringClusterResetConditionParams * _Nullable)params
                      completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            CeramicFilterMonitoring::Commands::ResetCondition::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeConditionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = CeramicFilterMonitoring::Attributes::Condition::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeConditionWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = CeramicFilterMonitoring::Attributes::Condition::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeConditionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = CeramicFilterMonitoring::Attributes::Condition::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeDegradationDirectionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = CeramicFilterMonitoring::Attributes::DegradationDirection::TypeInfo;
    return MTRReadAttribute<MTRCeramicFilterMonitoringClusterDegradationDirectionEnumAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeDegradationDirectionWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = CeramicFilterMonitoring::Attributes::DegradationDirection::TypeInfo;
    MTRSubscribeAttribute<MTRCeramicFilterMonitoringClusterDegradationDirectionEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeDegradationDirectionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCeramicFilterMonitoringClusterDegradationDirectionEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(CeramicFilterMonitoringClusterDegradationDirectionEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = CeramicFilterMonitoring::Attributes::DegradationDirection::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeChangeIndicationWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = CeramicFilterMonitoring::Attributes::ChangeIndication::TypeInfo;
    return MTRReadAttribute<MTRCeramicFilterMonitoringClusterChangeIndicationEnumAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeChangeIndicationWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = CeramicFilterMonitoring::Attributes::ChangeIndication::TypeInfo;
    MTRSubscribeAttribute<MTRCeramicFilterMonitoringClusterChangeIndicationEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeChangeIndicationWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCeramicFilterMonitoringClusterChangeIndicationEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(CeramicFilterMonitoringClusterChangeIndicationEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = CeramicFilterMonitoring::Attributes::ChangeIndication::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeInPlaceIndicatorWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = CeramicFilterMonitoring::Attributes::InPlaceIndicator::TypeInfo;
    return MTRReadAttribute<MTRBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeInPlaceIndicatorWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = CeramicFilterMonitoring::Attributes::InPlaceIndicator::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeInPlaceIndicatorWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = CeramicFilterMonitoring::Attributes::InPlaceIndicator::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = CeramicFilterMonitoring::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRCeramicFilterMonitoringGeneratedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = CeramicFilterMonitoring::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRCeramicFilterMonitoringGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCeramicFilterMonitoringGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(CeramicFilterMonitoringGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = CeramicFilterMonitoring::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = CeramicFilterMonitoring::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRCeramicFilterMonitoringAcceptedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = CeramicFilterMonitoring::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRCeramicFilterMonitoringAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCeramicFilterMonitoringAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(CeramicFilterMonitoringAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = CeramicFilterMonitoring::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = CeramicFilterMonitoring::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRCeramicFilterMonitoringEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = CeramicFilterMonitoring::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRCeramicFilterMonitoringEventListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCeramicFilterMonitoringEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(CeramicFilterMonitoringEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = CeramicFilterMonitoring::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = CeramicFilterMonitoring::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRCeramicFilterMonitoringAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = CeramicFilterMonitoring::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRCeramicFilterMonitoringAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCeramicFilterMonitoringAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(CeramicFilterMonitoringAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = CeramicFilterMonitoring::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = CeramicFilterMonitoring::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = CeramicFilterMonitoring::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = CeramicFilterMonitoring::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = CeramicFilterMonitoring::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = CeramicFilterMonitoring::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = CeramicFilterMonitoring::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterElectrostaticFilterMonitoring

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)resetConditionWithCompletion:(MTRStatusCompletion)completion
{
    [self resetConditionWithParams:nil completion:completion];
}
- (void)resetConditionWithParams:(MTRElectrostaticFilterMonitoringClusterResetConditionParams * _Nullable)params
                      completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            ElectrostaticFilterMonitoring::Commands::ResetCondition::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeConditionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectrostaticFilterMonitoring::Attributes::Condition::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeConditionWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectrostaticFilterMonitoring::Attributes::Condition::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeConditionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectrostaticFilterMonitoring::Attributes::Condition::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeDegradationDirectionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectrostaticFilterMonitoring::Attributes::DegradationDirection::TypeInfo;
    return MTRReadAttribute<MTRElectrostaticFilterMonitoringClusterDegradationDirectionEnumAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeDegradationDirectionWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectrostaticFilterMonitoring::Attributes::DegradationDirection::TypeInfo;
    MTRSubscribeAttribute<MTRElectrostaticFilterMonitoringClusterDegradationDirectionEnumAttributeCallbackSubscriptionBridge,
        NSNumber, TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device,
        self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeDegradationDirectionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRElectrostaticFilterMonitoringClusterDegradationDirectionEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ElectrostaticFilterMonitoringClusterDegradationDirectionEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectrostaticFilterMonitoring::Attributes::DegradationDirection::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeChangeIndicationWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectrostaticFilterMonitoring::Attributes::ChangeIndication::TypeInfo;
    return MTRReadAttribute<MTRElectrostaticFilterMonitoringClusterChangeIndicationEnumAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeChangeIndicationWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectrostaticFilterMonitoring::Attributes::ChangeIndication::TypeInfo;
    MTRSubscribeAttribute<MTRElectrostaticFilterMonitoringClusterChangeIndicationEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeChangeIndicationWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRElectrostaticFilterMonitoringClusterChangeIndicationEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ElectrostaticFilterMonitoringClusterChangeIndicationEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectrostaticFilterMonitoring::Attributes::ChangeIndication::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeInPlaceIndicatorWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectrostaticFilterMonitoring::Attributes::InPlaceIndicator::TypeInfo;
    return MTRReadAttribute<MTRBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeInPlaceIndicatorWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectrostaticFilterMonitoring::Attributes::InPlaceIndicator::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeInPlaceIndicatorWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectrostaticFilterMonitoring::Attributes::InPlaceIndicator::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectrostaticFilterMonitoring::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRElectrostaticFilterMonitoringGeneratedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectrostaticFilterMonitoring::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRElectrostaticFilterMonitoringGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRElectrostaticFilterMonitoringGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ElectrostaticFilterMonitoringGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectrostaticFilterMonitoring::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectrostaticFilterMonitoring::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRElectrostaticFilterMonitoringAcceptedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectrostaticFilterMonitoring::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRElectrostaticFilterMonitoringAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRElectrostaticFilterMonitoringAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ElectrostaticFilterMonitoringAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectrostaticFilterMonitoring::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectrostaticFilterMonitoring::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRElectrostaticFilterMonitoringEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectrostaticFilterMonitoring::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRElectrostaticFilterMonitoringEventListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRElectrostaticFilterMonitoringEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ElectrostaticFilterMonitoringEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectrostaticFilterMonitoring::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectrostaticFilterMonitoring::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRElectrostaticFilterMonitoringAttributeListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectrostaticFilterMonitoring::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRElectrostaticFilterMonitoringAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRElectrostaticFilterMonitoringAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ElectrostaticFilterMonitoringAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectrostaticFilterMonitoring::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectrostaticFilterMonitoring::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectrostaticFilterMonitoring::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectrostaticFilterMonitoring::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectrostaticFilterMonitoring::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectrostaticFilterMonitoring::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectrostaticFilterMonitoring::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterUVFilterMonitoring

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)resetConditionWithCompletion:(MTRStatusCompletion)completion
{
    [self resetConditionWithParams:nil completion:completion];
}
- (void)resetConditionWithParams:(MTRUVFilterMonitoringClusterResetConditionParams * _Nullable)params
                      completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            UvFilterMonitoring::Commands::ResetCondition::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeConditionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UvFilterMonitoring::Attributes::Condition::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeConditionWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UvFilterMonitoring::Attributes::Condition::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeConditionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UvFilterMonitoring::Attributes::Condition::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeDegradationDirectionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UvFilterMonitoring::Attributes::DegradationDirection::TypeInfo;
    return MTRReadAttribute<MTRUVFilterMonitoringClusterDegradationDirectionEnumAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeDegradationDirectionWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UvFilterMonitoring::Attributes::DegradationDirection::TypeInfo;
    MTRSubscribeAttribute<MTRUVFilterMonitoringClusterDegradationDirectionEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeDegradationDirectionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRUVFilterMonitoringClusterDegradationDirectionEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(UVFilterMonitoringClusterDegradationDirectionEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UvFilterMonitoring::Attributes::DegradationDirection::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeChangeIndicationWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UvFilterMonitoring::Attributes::ChangeIndication::TypeInfo;
    return MTRReadAttribute<MTRUVFilterMonitoringClusterChangeIndicationEnumAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeChangeIndicationWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UvFilterMonitoring::Attributes::ChangeIndication::TypeInfo;
    MTRSubscribeAttribute<MTRUVFilterMonitoringClusterChangeIndicationEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeChangeIndicationWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRUVFilterMonitoringClusterChangeIndicationEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(UVFilterMonitoringClusterChangeIndicationEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UvFilterMonitoring::Attributes::ChangeIndication::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeInPlaceIndicatorWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UvFilterMonitoring::Attributes::InPlaceIndicator::TypeInfo;
    return MTRReadAttribute<MTRBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeInPlaceIndicatorWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UvFilterMonitoring::Attributes::InPlaceIndicator::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeInPlaceIndicatorWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UvFilterMonitoring::Attributes::InPlaceIndicator::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UvFilterMonitoring::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRUVFilterMonitoringGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UvFilterMonitoring::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRUVFilterMonitoringGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRUVFilterMonitoringGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(UVFilterMonitoringGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UvFilterMonitoring::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UvFilterMonitoring::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRUVFilterMonitoringAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UvFilterMonitoring::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRUVFilterMonitoringAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRUVFilterMonitoringAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(UVFilterMonitoringAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UvFilterMonitoring::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UvFilterMonitoring::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRUVFilterMonitoringEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UvFilterMonitoring::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRUVFilterMonitoringEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRUVFilterMonitoringEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(UVFilterMonitoringEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UvFilterMonitoring::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UvFilterMonitoring::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRUVFilterMonitoringAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UvFilterMonitoring::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRUVFilterMonitoringAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRUVFilterMonitoringAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(UVFilterMonitoringAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UvFilterMonitoring::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UvFilterMonitoring::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UvFilterMonitoring::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UvFilterMonitoring::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UvFilterMonitoring::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UvFilterMonitoring::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UvFilterMonitoring::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterIonizingFilterMonitoring

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)resetConditionWithCompletion:(MTRStatusCompletion)completion
{
    [self resetConditionWithParams:nil completion:completion];
}
- (void)resetConditionWithParams:(MTRIonizingFilterMonitoringClusterResetConditionParams * _Nullable)params
                      completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            IonizingFilterMonitoring::Commands::ResetCondition::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeConditionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = IonizingFilterMonitoring::Attributes::Condition::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeConditionWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = IonizingFilterMonitoring::Attributes::Condition::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeConditionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = IonizingFilterMonitoring::Attributes::Condition::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeDegradationDirectionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = IonizingFilterMonitoring::Attributes::DegradationDirection::TypeInfo;
    return MTRReadAttribute<MTRIonizingFilterMonitoringClusterDegradationDirectionEnumAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeDegradationDirectionWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = IonizingFilterMonitoring::Attributes::DegradationDirection::TypeInfo;
    MTRSubscribeAttribute<MTRIonizingFilterMonitoringClusterDegradationDirectionEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeDegradationDirectionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRIonizingFilterMonitoringClusterDegradationDirectionEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(IonizingFilterMonitoringClusterDegradationDirectionEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = IonizingFilterMonitoring::Attributes::DegradationDirection::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeChangeIndicationWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = IonizingFilterMonitoring::Attributes::ChangeIndication::TypeInfo;
    return MTRReadAttribute<MTRIonizingFilterMonitoringClusterChangeIndicationEnumAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeChangeIndicationWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = IonizingFilterMonitoring::Attributes::ChangeIndication::TypeInfo;
    MTRSubscribeAttribute<MTRIonizingFilterMonitoringClusterChangeIndicationEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeChangeIndicationWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRIonizingFilterMonitoringClusterChangeIndicationEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(IonizingFilterMonitoringClusterChangeIndicationEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = IonizingFilterMonitoring::Attributes::ChangeIndication::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeInPlaceIndicatorWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = IonizingFilterMonitoring::Attributes::InPlaceIndicator::TypeInfo;
    return MTRReadAttribute<MTRBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeInPlaceIndicatorWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = IonizingFilterMonitoring::Attributes::InPlaceIndicator::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeInPlaceIndicatorWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = IonizingFilterMonitoring::Attributes::InPlaceIndicator::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = IonizingFilterMonitoring::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRIonizingFilterMonitoringGeneratedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = IonizingFilterMonitoring::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRIonizingFilterMonitoringGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRIonizingFilterMonitoringGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(IonizingFilterMonitoringGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = IonizingFilterMonitoring::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = IonizingFilterMonitoring::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRIonizingFilterMonitoringAcceptedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = IonizingFilterMonitoring::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRIonizingFilterMonitoringAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRIonizingFilterMonitoringAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(IonizingFilterMonitoringAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = IonizingFilterMonitoring::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = IonizingFilterMonitoring::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRIonizingFilterMonitoringEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = IonizingFilterMonitoring::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRIonizingFilterMonitoringEventListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRIonizingFilterMonitoringEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(IonizingFilterMonitoringEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = IonizingFilterMonitoring::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = IonizingFilterMonitoring::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRIonizingFilterMonitoringAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = IonizingFilterMonitoring::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRIonizingFilterMonitoringAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRIonizingFilterMonitoringAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(IonizingFilterMonitoringAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = IonizingFilterMonitoring::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = IonizingFilterMonitoring::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = IonizingFilterMonitoring::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = IonizingFilterMonitoring::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = IonizingFilterMonitoring::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = IonizingFilterMonitoring::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = IonizingFilterMonitoring::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterZeoliteFilterMonitoring

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)resetConditionWithCompletion:(MTRStatusCompletion)completion
{
    [self resetConditionWithParams:nil completion:completion];
}
- (void)resetConditionWithParams:(MTRZeoliteFilterMonitoringClusterResetConditionParams * _Nullable)params
                      completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            ZeoliteFilterMonitoring::Commands::ResetCondition::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeConditionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ZeoliteFilterMonitoring::Attributes::Condition::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeConditionWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ZeoliteFilterMonitoring::Attributes::Condition::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeConditionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ZeoliteFilterMonitoring::Attributes::Condition::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeDegradationDirectionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ZeoliteFilterMonitoring::Attributes::DegradationDirection::TypeInfo;
    return MTRReadAttribute<MTRZeoliteFilterMonitoringClusterDegradationDirectionEnumAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeDegradationDirectionWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ZeoliteFilterMonitoring::Attributes::DegradationDirection::TypeInfo;
    MTRSubscribeAttribute<MTRZeoliteFilterMonitoringClusterDegradationDirectionEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeDegradationDirectionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRZeoliteFilterMonitoringClusterDegradationDirectionEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ZeoliteFilterMonitoringClusterDegradationDirectionEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ZeoliteFilterMonitoring::Attributes::DegradationDirection::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeChangeIndicationWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ZeoliteFilterMonitoring::Attributes::ChangeIndication::TypeInfo;
    return MTRReadAttribute<MTRZeoliteFilterMonitoringClusterChangeIndicationEnumAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeChangeIndicationWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ZeoliteFilterMonitoring::Attributes::ChangeIndication::TypeInfo;
    MTRSubscribeAttribute<MTRZeoliteFilterMonitoringClusterChangeIndicationEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeChangeIndicationWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRZeoliteFilterMonitoringClusterChangeIndicationEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ZeoliteFilterMonitoringClusterChangeIndicationEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ZeoliteFilterMonitoring::Attributes::ChangeIndication::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeInPlaceIndicatorWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ZeoliteFilterMonitoring::Attributes::InPlaceIndicator::TypeInfo;
    return MTRReadAttribute<MTRBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeInPlaceIndicatorWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ZeoliteFilterMonitoring::Attributes::InPlaceIndicator::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeInPlaceIndicatorWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ZeoliteFilterMonitoring::Attributes::InPlaceIndicator::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ZeoliteFilterMonitoring::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRZeoliteFilterMonitoringGeneratedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ZeoliteFilterMonitoring::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRZeoliteFilterMonitoringGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRZeoliteFilterMonitoringGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ZeoliteFilterMonitoringGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ZeoliteFilterMonitoring::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ZeoliteFilterMonitoring::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRZeoliteFilterMonitoringAcceptedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ZeoliteFilterMonitoring::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRZeoliteFilterMonitoringAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRZeoliteFilterMonitoringAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ZeoliteFilterMonitoringAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ZeoliteFilterMonitoring::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ZeoliteFilterMonitoring::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRZeoliteFilterMonitoringEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ZeoliteFilterMonitoring::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRZeoliteFilterMonitoringEventListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRZeoliteFilterMonitoringEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ZeoliteFilterMonitoringEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ZeoliteFilterMonitoring::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ZeoliteFilterMonitoring::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRZeoliteFilterMonitoringAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ZeoliteFilterMonitoring::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRZeoliteFilterMonitoringAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRZeoliteFilterMonitoringAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ZeoliteFilterMonitoringAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ZeoliteFilterMonitoring::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ZeoliteFilterMonitoring::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ZeoliteFilterMonitoring::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ZeoliteFilterMonitoring::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ZeoliteFilterMonitoring::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ZeoliteFilterMonitoring::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ZeoliteFilterMonitoring::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterOzoneFilterMonitoring

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)resetConditionWithCompletion:(MTRStatusCompletion)completion
{
    [self resetConditionWithParams:nil completion:completion];
}
- (void)resetConditionWithParams:(MTROzoneFilterMonitoringClusterResetConditionParams * _Nullable)params
                      completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            OzoneFilterMonitoring::Commands::ResetCondition::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeConditionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OzoneFilterMonitoring::Attributes::Condition::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeConditionWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OzoneFilterMonitoring::Attributes::Condition::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeConditionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OzoneFilterMonitoring::Attributes::Condition::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeDegradationDirectionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OzoneFilterMonitoring::Attributes::DegradationDirection::TypeInfo;
    return MTRReadAttribute<MTROzoneFilterMonitoringClusterDegradationDirectionEnumAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeDegradationDirectionWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OzoneFilterMonitoring::Attributes::DegradationDirection::TypeInfo;
    MTRSubscribeAttribute<MTROzoneFilterMonitoringClusterDegradationDirectionEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeDegradationDirectionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTROzoneFilterMonitoringClusterDegradationDirectionEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(OzoneFilterMonitoringClusterDegradationDirectionEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OzoneFilterMonitoring::Attributes::DegradationDirection::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeChangeIndicationWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OzoneFilterMonitoring::Attributes::ChangeIndication::TypeInfo;
    return MTRReadAttribute<MTROzoneFilterMonitoringClusterChangeIndicationEnumAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeChangeIndicationWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OzoneFilterMonitoring::Attributes::ChangeIndication::TypeInfo;
    MTRSubscribeAttribute<MTROzoneFilterMonitoringClusterChangeIndicationEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeChangeIndicationWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTROzoneFilterMonitoringClusterChangeIndicationEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(OzoneFilterMonitoringClusterChangeIndicationEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OzoneFilterMonitoring::Attributes::ChangeIndication::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeInPlaceIndicatorWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OzoneFilterMonitoring::Attributes::InPlaceIndicator::TypeInfo;
    return MTRReadAttribute<MTRBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeInPlaceIndicatorWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OzoneFilterMonitoring::Attributes::InPlaceIndicator::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeInPlaceIndicatorWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OzoneFilterMonitoring::Attributes::InPlaceIndicator::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OzoneFilterMonitoring::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTROzoneFilterMonitoringGeneratedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OzoneFilterMonitoring::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTROzoneFilterMonitoringGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTROzoneFilterMonitoringGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(OzoneFilterMonitoringGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OzoneFilterMonitoring::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OzoneFilterMonitoring::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTROzoneFilterMonitoringAcceptedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OzoneFilterMonitoring::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTROzoneFilterMonitoringAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTROzoneFilterMonitoringAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(OzoneFilterMonitoringAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OzoneFilterMonitoring::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OzoneFilterMonitoring::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTROzoneFilterMonitoringEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OzoneFilterMonitoring::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTROzoneFilterMonitoringEventListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTROzoneFilterMonitoringEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(OzoneFilterMonitoringEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OzoneFilterMonitoring::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OzoneFilterMonitoring::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTROzoneFilterMonitoringAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OzoneFilterMonitoring::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTROzoneFilterMonitoringAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTROzoneFilterMonitoringAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(OzoneFilterMonitoringAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OzoneFilterMonitoring::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OzoneFilterMonitoring::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OzoneFilterMonitoring::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OzoneFilterMonitoring::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OzoneFilterMonitoring::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OzoneFilterMonitoring::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OzoneFilterMonitoring::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterWaterTankMonitoring

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)resetConditionWithCompletion:(MTRStatusCompletion)completion
{
    [self resetConditionWithParams:nil completion:completion];
}
- (void)resetConditionWithParams:(MTRWaterTankMonitoringClusterResetConditionParams * _Nullable)params
                      completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            WaterTankMonitoring::Commands::ResetCondition::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeConditionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WaterTankMonitoring::Attributes::Condition::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeConditionWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WaterTankMonitoring::Attributes::Condition::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeConditionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WaterTankMonitoring::Attributes::Condition::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeDegradationDirectionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WaterTankMonitoring::Attributes::DegradationDirection::TypeInfo;
    return MTRReadAttribute<MTRWaterTankMonitoringClusterDegradationDirectionEnumAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeDegradationDirectionWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WaterTankMonitoring::Attributes::DegradationDirection::TypeInfo;
    MTRSubscribeAttribute<MTRWaterTankMonitoringClusterDegradationDirectionEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeDegradationDirectionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRWaterTankMonitoringClusterDegradationDirectionEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(WaterTankMonitoringClusterDegradationDirectionEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WaterTankMonitoring::Attributes::DegradationDirection::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeChangeIndicationWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WaterTankMonitoring::Attributes::ChangeIndication::TypeInfo;
    return MTRReadAttribute<MTRWaterTankMonitoringClusterChangeIndicationEnumAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeChangeIndicationWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WaterTankMonitoring::Attributes::ChangeIndication::TypeInfo;
    MTRSubscribeAttribute<MTRWaterTankMonitoringClusterChangeIndicationEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeChangeIndicationWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRWaterTankMonitoringClusterChangeIndicationEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(WaterTankMonitoringClusterChangeIndicationEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WaterTankMonitoring::Attributes::ChangeIndication::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeInPlaceIndicatorWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WaterTankMonitoring::Attributes::InPlaceIndicator::TypeInfo;
    return MTRReadAttribute<MTRBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeInPlaceIndicatorWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WaterTankMonitoring::Attributes::InPlaceIndicator::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeInPlaceIndicatorWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WaterTankMonitoring::Attributes::InPlaceIndicator::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WaterTankMonitoring::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRWaterTankMonitoringGeneratedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WaterTankMonitoring::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRWaterTankMonitoringGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRWaterTankMonitoringGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(WaterTankMonitoringGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WaterTankMonitoring::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WaterTankMonitoring::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRWaterTankMonitoringAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WaterTankMonitoring::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRWaterTankMonitoringAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRWaterTankMonitoringAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(WaterTankMonitoringAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WaterTankMonitoring::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WaterTankMonitoring::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRWaterTankMonitoringEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WaterTankMonitoring::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRWaterTankMonitoringEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRWaterTankMonitoringEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(WaterTankMonitoringEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WaterTankMonitoring::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WaterTankMonitoring::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRWaterTankMonitoringAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WaterTankMonitoring::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRWaterTankMonitoringAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRWaterTankMonitoringAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(WaterTankMonitoringAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WaterTankMonitoring::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WaterTankMonitoring::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WaterTankMonitoring::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WaterTankMonitoring::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WaterTankMonitoring::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WaterTankMonitoring::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WaterTankMonitoring::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterFuelTankMonitoring

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)resetConditionWithCompletion:(MTRStatusCompletion)completion
{
    [self resetConditionWithParams:nil completion:completion];
}
- (void)resetConditionWithParams:(MTRFuelTankMonitoringClusterResetConditionParams * _Nullable)params
                      completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            FuelTankMonitoring::Commands::ResetCondition::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeConditionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FuelTankMonitoring::Attributes::Condition::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeConditionWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FuelTankMonitoring::Attributes::Condition::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeConditionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FuelTankMonitoring::Attributes::Condition::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeDegradationDirectionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FuelTankMonitoring::Attributes::DegradationDirection::TypeInfo;
    return MTRReadAttribute<MTRFuelTankMonitoringClusterDegradationDirectionEnumAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeDegradationDirectionWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FuelTankMonitoring::Attributes::DegradationDirection::TypeInfo;
    MTRSubscribeAttribute<MTRFuelTankMonitoringClusterDegradationDirectionEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeDegradationDirectionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRFuelTankMonitoringClusterDegradationDirectionEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(FuelTankMonitoringClusterDegradationDirectionEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FuelTankMonitoring::Attributes::DegradationDirection::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeChangeIndicationWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FuelTankMonitoring::Attributes::ChangeIndication::TypeInfo;
    return MTRReadAttribute<MTRFuelTankMonitoringClusterChangeIndicationEnumAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeChangeIndicationWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FuelTankMonitoring::Attributes::ChangeIndication::TypeInfo;
    MTRSubscribeAttribute<MTRFuelTankMonitoringClusterChangeIndicationEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeChangeIndicationWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRFuelTankMonitoringClusterChangeIndicationEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(FuelTankMonitoringClusterChangeIndicationEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FuelTankMonitoring::Attributes::ChangeIndication::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeInPlaceIndicatorWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FuelTankMonitoring::Attributes::InPlaceIndicator::TypeInfo;
    return MTRReadAttribute<MTRBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeInPlaceIndicatorWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FuelTankMonitoring::Attributes::InPlaceIndicator::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeInPlaceIndicatorWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FuelTankMonitoring::Attributes::InPlaceIndicator::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FuelTankMonitoring::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRFuelTankMonitoringGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FuelTankMonitoring::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRFuelTankMonitoringGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRFuelTankMonitoringGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(FuelTankMonitoringGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FuelTankMonitoring::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FuelTankMonitoring::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRFuelTankMonitoringAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FuelTankMonitoring::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRFuelTankMonitoringAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRFuelTankMonitoringAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(FuelTankMonitoringAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FuelTankMonitoring::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FuelTankMonitoring::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRFuelTankMonitoringEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FuelTankMonitoring::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRFuelTankMonitoringEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRFuelTankMonitoringEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(FuelTankMonitoringEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FuelTankMonitoring::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FuelTankMonitoring::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRFuelTankMonitoringAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FuelTankMonitoring::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRFuelTankMonitoringAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRFuelTankMonitoringAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(FuelTankMonitoringAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FuelTankMonitoring::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FuelTankMonitoring::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FuelTankMonitoring::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FuelTankMonitoring::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FuelTankMonitoring::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FuelTankMonitoring::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FuelTankMonitoring::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterInkCartridgeMonitoring

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)resetConditionWithCompletion:(MTRStatusCompletion)completion
{
    [self resetConditionWithParams:nil completion:completion];
}
- (void)resetConditionWithParams:(MTRInkCartridgeMonitoringClusterResetConditionParams * _Nullable)params
                      completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            InkCartridgeMonitoring::Commands::ResetCondition::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeConditionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = InkCartridgeMonitoring::Attributes::Condition::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeConditionWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = InkCartridgeMonitoring::Attributes::Condition::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeConditionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = InkCartridgeMonitoring::Attributes::Condition::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeDegradationDirectionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = InkCartridgeMonitoring::Attributes::DegradationDirection::TypeInfo;
    return MTRReadAttribute<MTRInkCartridgeMonitoringClusterDegradationDirectionEnumAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeDegradationDirectionWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = InkCartridgeMonitoring::Attributes::DegradationDirection::TypeInfo;
    MTRSubscribeAttribute<MTRInkCartridgeMonitoringClusterDegradationDirectionEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeDegradationDirectionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInkCartridgeMonitoringClusterDegradationDirectionEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(InkCartridgeMonitoringClusterDegradationDirectionEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = InkCartridgeMonitoring::Attributes::DegradationDirection::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeChangeIndicationWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = InkCartridgeMonitoring::Attributes::ChangeIndication::TypeInfo;
    return MTRReadAttribute<MTRInkCartridgeMonitoringClusterChangeIndicationEnumAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeChangeIndicationWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = InkCartridgeMonitoring::Attributes::ChangeIndication::TypeInfo;
    MTRSubscribeAttribute<MTRInkCartridgeMonitoringClusterChangeIndicationEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeChangeIndicationWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInkCartridgeMonitoringClusterChangeIndicationEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(InkCartridgeMonitoringClusterChangeIndicationEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = InkCartridgeMonitoring::Attributes::ChangeIndication::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeInPlaceIndicatorWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = InkCartridgeMonitoring::Attributes::InPlaceIndicator::TypeInfo;
    return MTRReadAttribute<MTRBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeInPlaceIndicatorWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = InkCartridgeMonitoring::Attributes::InPlaceIndicator::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeInPlaceIndicatorWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = InkCartridgeMonitoring::Attributes::InPlaceIndicator::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = InkCartridgeMonitoring::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRInkCartridgeMonitoringGeneratedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = InkCartridgeMonitoring::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRInkCartridgeMonitoringGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInkCartridgeMonitoringGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(InkCartridgeMonitoringGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = InkCartridgeMonitoring::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = InkCartridgeMonitoring::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRInkCartridgeMonitoringAcceptedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = InkCartridgeMonitoring::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRInkCartridgeMonitoringAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInkCartridgeMonitoringAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(InkCartridgeMonitoringAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = InkCartridgeMonitoring::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = InkCartridgeMonitoring::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRInkCartridgeMonitoringEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = InkCartridgeMonitoring::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRInkCartridgeMonitoringEventListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInkCartridgeMonitoringEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(InkCartridgeMonitoringEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = InkCartridgeMonitoring::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = InkCartridgeMonitoring::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRInkCartridgeMonitoringAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = InkCartridgeMonitoring::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRInkCartridgeMonitoringAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInkCartridgeMonitoringAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(InkCartridgeMonitoringAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = InkCartridgeMonitoring::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = InkCartridgeMonitoring::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = InkCartridgeMonitoring::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = InkCartridgeMonitoring::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = InkCartridgeMonitoring::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = InkCartridgeMonitoring::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = InkCartridgeMonitoring::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterTonerCartridgeMonitoring

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)resetConditionWithCompletion:(MTRStatusCompletion)completion
{
    [self resetConditionWithParams:nil completion:completion];
}
- (void)resetConditionWithParams:(MTRTonerCartridgeMonitoringClusterResetConditionParams * _Nullable)params
                      completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            TonerCartridgeMonitoring::Commands::ResetCondition::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeConditionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TonerCartridgeMonitoring::Attributes::Condition::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeConditionWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TonerCartridgeMonitoring::Attributes::Condition::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeConditionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TonerCartridgeMonitoring::Attributes::Condition::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeDegradationDirectionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TonerCartridgeMonitoring::Attributes::DegradationDirection::TypeInfo;
    return MTRReadAttribute<MTRTonerCartridgeMonitoringClusterDegradationDirectionEnumAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeDegradationDirectionWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TonerCartridgeMonitoring::Attributes::DegradationDirection::TypeInfo;
    MTRSubscribeAttribute<MTRTonerCartridgeMonitoringClusterDegradationDirectionEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeDegradationDirectionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRTonerCartridgeMonitoringClusterDegradationDirectionEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(TonerCartridgeMonitoringClusterDegradationDirectionEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TonerCartridgeMonitoring::Attributes::DegradationDirection::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeChangeIndicationWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TonerCartridgeMonitoring::Attributes::ChangeIndication::TypeInfo;
    return MTRReadAttribute<MTRTonerCartridgeMonitoringClusterChangeIndicationEnumAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeChangeIndicationWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TonerCartridgeMonitoring::Attributes::ChangeIndication::TypeInfo;
    MTRSubscribeAttribute<MTRTonerCartridgeMonitoringClusterChangeIndicationEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeChangeIndicationWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRTonerCartridgeMonitoringClusterChangeIndicationEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(TonerCartridgeMonitoringClusterChangeIndicationEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TonerCartridgeMonitoring::Attributes::ChangeIndication::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeInPlaceIndicatorWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TonerCartridgeMonitoring::Attributes::InPlaceIndicator::TypeInfo;
    return MTRReadAttribute<MTRBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeInPlaceIndicatorWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TonerCartridgeMonitoring::Attributes::InPlaceIndicator::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeInPlaceIndicatorWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TonerCartridgeMonitoring::Attributes::InPlaceIndicator::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TonerCartridgeMonitoring::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRTonerCartridgeMonitoringGeneratedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TonerCartridgeMonitoring::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRTonerCartridgeMonitoringGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRTonerCartridgeMonitoringGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(TonerCartridgeMonitoringGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TonerCartridgeMonitoring::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TonerCartridgeMonitoring::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRTonerCartridgeMonitoringAcceptedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TonerCartridgeMonitoring::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRTonerCartridgeMonitoringAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRTonerCartridgeMonitoringAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(TonerCartridgeMonitoringAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TonerCartridgeMonitoring::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TonerCartridgeMonitoring::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRTonerCartridgeMonitoringEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TonerCartridgeMonitoring::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRTonerCartridgeMonitoringEventListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRTonerCartridgeMonitoringEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(TonerCartridgeMonitoringEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TonerCartridgeMonitoring::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TonerCartridgeMonitoring::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRTonerCartridgeMonitoringAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TonerCartridgeMonitoring::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRTonerCartridgeMonitoringAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRTonerCartridgeMonitoringAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(TonerCartridgeMonitoringAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TonerCartridgeMonitoring::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TonerCartridgeMonitoring::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TonerCartridgeMonitoring::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TonerCartridgeMonitoring::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TonerCartridgeMonitoring::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TonerCartridgeMonitoring::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TonerCartridgeMonitoring::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterDoorLock

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)lockDoorWithParams:(MTRDoorLockClusterLockDoorParams * _Nullable)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            DoorLock::Commands::LockDoor::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            if (!timedInvokeTimeoutMs.HasValue()) {
                timedInvokeTimeoutMs.SetValue(10000);
            }
            if (params != nil) {
                if (params.pinCode != nil) {
                    auto & definedValue_0 = request.PINCode.Emplace();
                    definedValue_0 = [self asByteSpan:params.pinCode];
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)unlockDoorWithParams:(MTRDoorLockClusterUnlockDoorParams * _Nullable)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            DoorLock::Commands::UnlockDoor::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            if (!timedInvokeTimeoutMs.HasValue()) {
                timedInvokeTimeoutMs.SetValue(10000);
            }
            if (params != nil) {
                if (params.pinCode != nil) {
                    auto & definedValue_0 = request.PINCode.Emplace();
                    definedValue_0 = [self asByteSpan:params.pinCode];
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)unlockWithTimeoutWithParams:(MTRDoorLockClusterUnlockWithTimeoutParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            DoorLock::Commands::UnlockWithTimeout::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            if (!timedInvokeTimeoutMs.HasValue()) {
                timedInvokeTimeoutMs.SetValue(10000);
            }
            request.timeout = params.timeout.unsignedShortValue;
            if (params.pinCode != nil) {
                auto & definedValue_0 = request.PINCode.Emplace();
                definedValue_0 = [self asByteSpan:params.pinCode];
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)setWeekDayScheduleWithParams:(MTRDoorLockClusterSetWeekDayScheduleParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            DoorLock::Commands::SetWeekDaySchedule::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.weekDayIndex = params.weekDayIndex.unsignedCharValue;
            request.userIndex = params.userIndex.unsignedShortValue;
            request.daysMask = static_cast<std::remove_reference_t<decltype(request.daysMask)>>(params.daysMask.unsignedCharValue);
            request.startHour = params.startHour.unsignedCharValue;
            request.startMinute = params.startMinute.unsignedCharValue;
            request.endHour = params.endHour.unsignedCharValue;
            request.endMinute = params.endMinute.unsignedCharValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)getWeekDayScheduleWithParams:(MTRDoorLockClusterGetWeekDayScheduleParams *)params
                          completion:(void (^)(MTRDoorLockClusterGetWeekDayScheduleResponseParams * _Nullable data,
                                         NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRDoorLockClusterGetWeekDayScheduleResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            DoorLockClusterGetWeekDayScheduleResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRDoorLockClusterGetWeekDayScheduleResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            DoorLock::Commands::GetWeekDaySchedule::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.weekDayIndex = params.weekDayIndex.unsignedCharValue;
            request.userIndex = params.userIndex.unsignedShortValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)clearWeekDayScheduleWithParams:(MTRDoorLockClusterClearWeekDayScheduleParams *)params
                            completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            DoorLock::Commands::ClearWeekDaySchedule::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.weekDayIndex = params.weekDayIndex.unsignedCharValue;
            request.userIndex = params.userIndex.unsignedShortValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)setYearDayScheduleWithParams:(MTRDoorLockClusterSetYearDayScheduleParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            DoorLock::Commands::SetYearDaySchedule::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.yearDayIndex = params.yearDayIndex.unsignedCharValue;
            request.userIndex = params.userIndex.unsignedShortValue;
            request.localStartTime = params.localStartTime.unsignedIntValue;
            request.localEndTime = params.localEndTime.unsignedIntValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)getYearDayScheduleWithParams:(MTRDoorLockClusterGetYearDayScheduleParams *)params
                          completion:(void (^)(MTRDoorLockClusterGetYearDayScheduleResponseParams * _Nullable data,
                                         NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRDoorLockClusterGetYearDayScheduleResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            DoorLockClusterGetYearDayScheduleResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRDoorLockClusterGetYearDayScheduleResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            DoorLock::Commands::GetYearDaySchedule::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.yearDayIndex = params.yearDayIndex.unsignedCharValue;
            request.userIndex = params.userIndex.unsignedShortValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)clearYearDayScheduleWithParams:(MTRDoorLockClusterClearYearDayScheduleParams *)params
                            completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            DoorLock::Commands::ClearYearDaySchedule::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.yearDayIndex = params.yearDayIndex.unsignedCharValue;
            request.userIndex = params.userIndex.unsignedShortValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)setHolidayScheduleWithParams:(MTRDoorLockClusterSetHolidayScheduleParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            DoorLock::Commands::SetHolidaySchedule::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.holidayIndex = params.holidayIndex.unsignedCharValue;
            request.localStartTime = params.localStartTime.unsignedIntValue;
            request.localEndTime = params.localEndTime.unsignedIntValue;
            request.operatingMode
                = static_cast<std::remove_reference_t<decltype(request.operatingMode)>>(params.operatingMode.unsignedCharValue);

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)getHolidayScheduleWithParams:(MTRDoorLockClusterGetHolidayScheduleParams *)params
                          completion:(void (^)(MTRDoorLockClusterGetHolidayScheduleResponseParams * _Nullable data,
                                         NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRDoorLockClusterGetHolidayScheduleResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            DoorLockClusterGetHolidayScheduleResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRDoorLockClusterGetHolidayScheduleResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            DoorLock::Commands::GetHolidaySchedule::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.holidayIndex = params.holidayIndex.unsignedCharValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)clearHolidayScheduleWithParams:(MTRDoorLockClusterClearHolidayScheduleParams *)params
                            completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            DoorLock::Commands::ClearHolidaySchedule::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.holidayIndex = params.holidayIndex.unsignedCharValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)setUserWithParams:(MTRDoorLockClusterSetUserParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            DoorLock::Commands::SetUser::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            if (!timedInvokeTimeoutMs.HasValue()) {
                timedInvokeTimeoutMs.SetValue(10000);
            }
            request.operationType
                = static_cast<std::remove_reference_t<decltype(request.operationType)>>(params.operationType.unsignedCharValue);
            request.userIndex = params.userIndex.unsignedShortValue;
            if (params.userName == nil) {
                request.userName.SetNull();
            } else {
                auto & nonNullValue_0 = request.userName.SetNonNull();
                nonNullValue_0 = [self asCharSpan:params.userName];
            }
            if (params.userUniqueID == nil) {
                request.userUniqueID.SetNull();
            } else {
                auto & nonNullValue_0 = request.userUniqueID.SetNonNull();
                nonNullValue_0 = params.userUniqueID.unsignedIntValue;
            }
            if (params.userStatus == nil) {
                request.userStatus.SetNull();
            } else {
                auto & nonNullValue_0 = request.userStatus.SetNonNull();
                nonNullValue_0
                    = static_cast<std::remove_reference_t<decltype(nonNullValue_0)>>(params.userStatus.unsignedCharValue);
            }
            if (params.userType == nil) {
                request.userType.SetNull();
            } else {
                auto & nonNullValue_0 = request.userType.SetNonNull();
                nonNullValue_0 = static_cast<std::remove_reference_t<decltype(nonNullValue_0)>>(params.userType.unsignedCharValue);
            }
            if (params.credentialRule == nil) {
                request.credentialRule.SetNull();
            } else {
                auto & nonNullValue_0 = request.credentialRule.SetNonNull();
                nonNullValue_0
                    = static_cast<std::remove_reference_t<decltype(nonNullValue_0)>>(params.credentialRule.unsignedCharValue);
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)getUserWithParams:(MTRDoorLockClusterGetUserParams *)params
               completion:(void (^)(MTRDoorLockClusterGetUserResponseParams * _Nullable data, NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRDoorLockClusterGetUserResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DoorLockClusterGetUserResponseCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRDoorLockClusterGetUserResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            DoorLock::Commands::GetUser::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.userIndex = params.userIndex.unsignedShortValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)clearUserWithParams:(MTRDoorLockClusterClearUserParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            DoorLock::Commands::ClearUser::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            if (!timedInvokeTimeoutMs.HasValue()) {
                timedInvokeTimeoutMs.SetValue(10000);
            }
            request.userIndex = params.userIndex.unsignedShortValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)setCredentialWithParams:(MTRDoorLockClusterSetCredentialParams *)params
                     completion:(void (^)(MTRDoorLockClusterSetCredentialResponseParams * _Nullable data,
                                    NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRDoorLockClusterSetCredentialResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            DoorLockClusterSetCredentialResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRDoorLockClusterSetCredentialResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            DoorLock::Commands::SetCredential::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            if (!timedInvokeTimeoutMs.HasValue()) {
                timedInvokeTimeoutMs.SetValue(10000);
            }
            request.operationType
                = static_cast<std::remove_reference_t<decltype(request.operationType)>>(params.operationType.unsignedCharValue);
            request.credential.credentialType = static_cast<std::remove_reference_t<decltype(request.credential.credentialType)>>(
                params.credential.credentialType.unsignedCharValue);
            request.credential.credentialIndex = params.credential.credentialIndex.unsignedShortValue;
            request.credentialData = [self asByteSpan:params.credentialData];
            if (params.userIndex == nil) {
                request.userIndex.SetNull();
            } else {
                auto & nonNullValue_0 = request.userIndex.SetNonNull();
                nonNullValue_0 = params.userIndex.unsignedShortValue;
            }
            if (params.userStatus == nil) {
                request.userStatus.SetNull();
            } else {
                auto & nonNullValue_0 = request.userStatus.SetNonNull();
                nonNullValue_0
                    = static_cast<std::remove_reference_t<decltype(nonNullValue_0)>>(params.userStatus.unsignedCharValue);
            }
            if (params.userType == nil) {
                request.userType.SetNull();
            } else {
                auto & nonNullValue_0 = request.userType.SetNonNull();
                nonNullValue_0 = static_cast<std::remove_reference_t<decltype(nonNullValue_0)>>(params.userType.unsignedCharValue);
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)getCredentialStatusWithParams:(MTRDoorLockClusterGetCredentialStatusParams *)params
                           completion:(void (^)(MTRDoorLockClusterGetCredentialStatusResponseParams * _Nullable data,
                                          NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRDoorLockClusterGetCredentialStatusResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            DoorLockClusterGetCredentialStatusResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRDoorLockClusterGetCredentialStatusResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            DoorLock::Commands::GetCredentialStatus::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.credential.credentialType = static_cast<std::remove_reference_t<decltype(request.credential.credentialType)>>(
                params.credential.credentialType.unsignedCharValue);
            request.credential.credentialIndex = params.credential.credentialIndex.unsignedShortValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)clearCredentialWithParams:(MTRDoorLockClusterClearCredentialParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            DoorLock::Commands::ClearCredential::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            if (!timedInvokeTimeoutMs.HasValue()) {
                timedInvokeTimeoutMs.SetValue(10000);
            }
            if (params.credential == nil) {
                request.credential.SetNull();
            } else {
                auto & nonNullValue_0 = request.credential.SetNonNull();
                nonNullValue_0.credentialType = static_cast<std::remove_reference_t<decltype(nonNullValue_0.credentialType)>>(
                    params.credential.credentialType.unsignedCharValue);
                nonNullValue_0.credentialIndex = params.credential.credentialIndex.unsignedShortValue;
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)unboltDoorWithParams:(MTRDoorLockClusterUnboltDoorParams * _Nullable)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            DoorLock::Commands::UnboltDoor::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            if (!timedInvokeTimeoutMs.HasValue()) {
                timedInvokeTimeoutMs.SetValue(10000);
            }
            if (params != nil) {
                if (params.pinCode != nil) {
                    auto & definedValue_0 = request.PINCode.Emplace();
                    definedValue_0 = [self asByteSpan:params.pinCode];
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeLockStateWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DoorLock::Attributes::LockState::TypeInfo;
    return MTRReadAttribute<MTRNullableDoorLockClusterDlLockStateAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeLockStateWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = DoorLock::Attributes::LockState::TypeInfo;
    MTRSubscribeAttribute<MTRNullableDoorLockClusterDlLockStateAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeLockStateWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableDoorLockClusterDlLockStateAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(NullableDoorLockClusterDlLockStateAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::LockState::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeLockTypeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DoorLock::Attributes::LockType::TypeInfo;
    return MTRReadAttribute<MTRDoorLockClusterDlLockTypeAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeLockTypeWithParams:(MTRSubscribeParams * _Nonnull)params
                     subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                               reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = DoorLock::Attributes::LockType::TypeInfo;
    MTRSubscribeAttribute<MTRDoorLockClusterDlLockTypeAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeLockTypeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                        completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRDoorLockClusterDlLockTypeAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(DoorLockClusterDlLockTypeAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::LockType::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeActuatorEnabledWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DoorLock::Attributes::ActuatorEnabled::TypeInfo;
    return MTRReadAttribute<MTRBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeActuatorEnabledWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = DoorLock::Attributes::ActuatorEnabled::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeActuatorEnabledWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::ActuatorEnabled::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeDoorStateWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DoorLock::Attributes::DoorState::TypeInfo;
    return MTRReadAttribute<MTRNullableDoorLockClusterDoorStateEnumAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeDoorStateWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = DoorLock::Attributes::DoorState::TypeInfo;
    MTRSubscribeAttribute<MTRNullableDoorLockClusterDoorStateEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeDoorStateWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableDoorLockClusterDoorStateEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(NullableDoorLockClusterDoorStateEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::DoorState::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeDoorOpenEventsWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DoorLock::Attributes::DoorOpenEvents::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeDoorOpenEventsWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeDoorOpenEventsWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeDoorOpenEventsWithValue:(NSNumber * _Nonnull)value
                                       params:(MTRWriteParams * _Nullable)params
                                   completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = DoorLock::Attributes::DoorOpenEvents::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedIntValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeDoorOpenEventsWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = DoorLock::Attributes::DoorOpenEvents::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeDoorOpenEventsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::DoorOpenEvents::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeDoorClosedEventsWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DoorLock::Attributes::DoorClosedEvents::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeDoorClosedEventsWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeDoorClosedEventsWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeDoorClosedEventsWithValue:(NSNumber * _Nonnull)value
                                         params:(MTRWriteParams * _Nullable)params
                                     completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = DoorLock::Attributes::DoorClosedEvents::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedIntValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeDoorClosedEventsWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = DoorLock::Attributes::DoorClosedEvents::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeDoorClosedEventsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::DoorClosedEvents::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeOpenPeriodWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DoorLock::Attributes::OpenPeriod::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeOpenPeriodWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeOpenPeriodWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeOpenPeriodWithValue:(NSNumber * _Nonnull)value
                                   params:(MTRWriteParams * _Nullable)params
                               completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = DoorLock::Attributes::OpenPeriod::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeOpenPeriodWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = DoorLock::Attributes::OpenPeriod::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeOpenPeriodWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::OpenPeriod::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNumberOfTotalUsersSupportedWithCompletion:(void (^)(
                                                                   NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DoorLock::Attributes::NumberOfTotalUsersSupported::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeNumberOfTotalUsersSupportedWithParams:(MTRSubscribeParams * _Nonnull)params
                                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = DoorLock::Attributes::NumberOfTotalUsersSupported::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNumberOfTotalUsersSupportedWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                             endpoint:(NSNumber *)endpoint
                                                                queue:(dispatch_queue_t)queue
                                                           completion:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::NumberOfTotalUsersSupported::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNumberOfPINUsersSupportedWithCompletion:(void (^)(
                                                                 NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DoorLock::Attributes::NumberOfPINUsersSupported::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeNumberOfPINUsersSupportedWithParams:(MTRSubscribeParams * _Nonnull)params
                                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = DoorLock::Attributes::NumberOfPINUsersSupported::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNumberOfPINUsersSupportedWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                           endpoint:(NSNumber *)endpoint
                                                              queue:(dispatch_queue_t)queue
                                                         completion:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::NumberOfPINUsersSupported::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNumberOfRFIDUsersSupportedWithCompletion:(void (^)(
                                                                  NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DoorLock::Attributes::NumberOfRFIDUsersSupported::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeNumberOfRFIDUsersSupportedWithParams:(MTRSubscribeParams * _Nonnull)params
                                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = DoorLock::Attributes::NumberOfRFIDUsersSupported::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNumberOfRFIDUsersSupportedWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                            endpoint:(NSNumber *)endpoint
                                                               queue:(dispatch_queue_t)queue
                                                          completion:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::NumberOfRFIDUsersSupported::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNumberOfWeekDaySchedulesSupportedPerUserWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                                NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DoorLock::Attributes::NumberOfWeekDaySchedulesSupportedPerUser::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeNumberOfWeekDaySchedulesSupportedPerUserWithParams:(MTRSubscribeParams * _Nonnull)params
                                                     subscriptionEstablished:
                                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                               reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                 NSError * _Nullable error))reportHandler
{
    using TypeInfo = DoorLock::Attributes::NumberOfWeekDaySchedulesSupportedPerUser::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNumberOfWeekDaySchedulesSupportedPerUserWithClusterStateCache:
            (MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                                          endpoint:(NSNumber *)endpoint
                                                                             queue:(dispatch_queue_t)queue
                                                                        completion:(void (^)(NSNumber * _Nullable value,
                                                                                       NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::NumberOfWeekDaySchedulesSupportedPerUser::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNumberOfYearDaySchedulesSupportedPerUserWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                                NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DoorLock::Attributes::NumberOfYearDaySchedulesSupportedPerUser::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeNumberOfYearDaySchedulesSupportedPerUserWithParams:(MTRSubscribeParams * _Nonnull)params
                                                     subscriptionEstablished:
                                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                               reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                 NSError * _Nullable error))reportHandler
{
    using TypeInfo = DoorLock::Attributes::NumberOfYearDaySchedulesSupportedPerUser::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNumberOfYearDaySchedulesSupportedPerUserWithClusterStateCache:
            (MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                                          endpoint:(NSNumber *)endpoint
                                                                             queue:(dispatch_queue_t)queue
                                                                        completion:(void (^)(NSNumber * _Nullable value,
                                                                                       NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::NumberOfYearDaySchedulesSupportedPerUser::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNumberOfHolidaySchedulesSupportedWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DoorLock::Attributes::NumberOfHolidaySchedulesSupported::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeNumberOfHolidaySchedulesSupportedWithParams:(MTRSubscribeParams * _Nonnull)params
                                              subscriptionEstablished:
                                                  (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                        reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))reportHandler
{
    using TypeInfo = DoorLock::Attributes::NumberOfHolidaySchedulesSupported::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNumberOfHolidaySchedulesSupportedWithClusterStateCache:
            (MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                                   endpoint:(NSNumber *)endpoint
                                                                      queue:(dispatch_queue_t)queue
                                                                 completion:(void (^)(NSNumber * _Nullable value,
                                                                                NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::NumberOfHolidaySchedulesSupported::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMaxPINCodeLengthWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DoorLock::Attributes::MaxPINCodeLength::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMaxPINCodeLengthWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = DoorLock::Attributes::MaxPINCodeLength::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMaxPINCodeLengthWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::MaxPINCodeLength::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMinPINCodeLengthWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DoorLock::Attributes::MinPINCodeLength::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMinPINCodeLengthWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = DoorLock::Attributes::MinPINCodeLength::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMinPINCodeLengthWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::MinPINCodeLength::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMaxRFIDCodeLengthWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DoorLock::Attributes::MaxRFIDCodeLength::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMaxRFIDCodeLengthWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = DoorLock::Attributes::MaxRFIDCodeLength::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMaxRFIDCodeLengthWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::MaxRFIDCodeLength::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMinRFIDCodeLengthWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DoorLock::Attributes::MinRFIDCodeLength::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMinRFIDCodeLengthWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = DoorLock::Attributes::MinRFIDCodeLength::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMinRFIDCodeLengthWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::MinRFIDCodeLength::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCredentialRulesSupportWithCompletion:(void (^)(
                                                              NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DoorLock::Attributes::CredentialRulesSupport::TypeInfo;
    return MTRReadAttribute<MTRDoorLockCredentialRulesSupportAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeCredentialRulesSupportWithParams:(MTRSubscribeParams * _Nonnull)params
                                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = DoorLock::Attributes::CredentialRulesSupport::TypeInfo;
    MTRSubscribeAttribute<MTRDoorLockCredentialRulesSupportAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeCredentialRulesSupportWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                                      completion:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completion
{
    auto * bridge = new MTRDoorLockCredentialRulesSupportAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(DoorLockCredentialRulesSupportAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::CredentialRulesSupport::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNumberOfCredentialsSupportedPerUserWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DoorLock::Attributes::NumberOfCredentialsSupportedPerUser::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeNumberOfCredentialsSupportedPerUserWithParams:(MTRSubscribeParams * _Nonnull)params
                                                subscriptionEstablished:
                                                    (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                          reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))reportHandler
{
    using TypeInfo = DoorLock::Attributes::NumberOfCredentialsSupportedPerUser::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNumberOfCredentialsSupportedPerUserWithClusterStateCache:
            (MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                                     endpoint:(NSNumber *)endpoint
                                                                        queue:(dispatch_queue_t)queue
                                                                   completion:(void (^)(NSNumber * _Nullable value,
                                                                                  NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::NumberOfCredentialsSupportedPerUser::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeLanguageWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DoorLock::Attributes::Language::TypeInfo;
    return MTRReadAttribute<MTRCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeLanguageWithValue:(NSString * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeLanguageWithValue:(NSString * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeLanguageWithValue:(NSString * _Nonnull)value
                                 params:(MTRWriteParams * _Nullable)params
                             completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = DoorLock::Attributes::Language::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = [self asCharSpan:value];

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeLanguageWithParams:(MTRSubscribeParams * _Nonnull)params
                     subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                               reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = DoorLock::Attributes::Language::TypeInfo;
    MTRSubscribeAttribute<MTRCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeLanguageWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                        completion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(CharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::Language::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeLEDSettingsWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DoorLock::Attributes::LEDSettings::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeLEDSettingsWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeLEDSettingsWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeLEDSettingsWithValue:(NSNumber * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                                completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = DoorLock::Attributes::LEDSettings::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeLEDSettingsWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = DoorLock::Attributes::LEDSettings::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeLEDSettingsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::LEDSettings::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAutoRelockTimeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DoorLock::Attributes::AutoRelockTime::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeAutoRelockTimeWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeAutoRelockTimeWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeAutoRelockTimeWithValue:(NSNumber * _Nonnull)value
                                       params:(MTRWriteParams * _Nullable)params
                                   completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = DoorLock::Attributes::AutoRelockTime::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedIntValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeAutoRelockTimeWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = DoorLock::Attributes::AutoRelockTime::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAutoRelockTimeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::AutoRelockTime::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSoundVolumeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DoorLock::Attributes::SoundVolume::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeSoundVolumeWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeSoundVolumeWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeSoundVolumeWithValue:(NSNumber * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                                completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = DoorLock::Attributes::SoundVolume::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeSoundVolumeWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = DoorLock::Attributes::SoundVolume::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeSoundVolumeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::SoundVolume::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeOperatingModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DoorLock::Attributes::OperatingMode::TypeInfo;
    return MTRReadAttribute<MTRDoorLockClusterOperatingModeEnumAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeOperatingModeWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeOperatingModeWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeOperatingModeWithValue:(NSNumber * _Nonnull)value
                                      params:(MTRWriteParams * _Nullable)params
                                  completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = DoorLock::Attributes::OperatingMode::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = static_cast<std::remove_reference_t<decltype(cppValue)>>(value.unsignedCharValue);

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeOperatingModeWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = DoorLock::Attributes::OperatingMode::TypeInfo;
    MTRSubscribeAttribute<MTRDoorLockClusterOperatingModeEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeOperatingModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRDoorLockClusterOperatingModeEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(DoorLockClusterOperatingModeEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::OperatingMode::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSupportedOperatingModesWithCompletion:(void (^)(
                                                               NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DoorLock::Attributes::SupportedOperatingModes::TypeInfo;
    return MTRReadAttribute<MTRDoorLockSupportedOperatingModesAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeSupportedOperatingModesWithParams:(MTRSubscribeParams * _Nonnull)params
                                    subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = DoorLock::Attributes::SupportedOperatingModes::TypeInfo;
    MTRSubscribeAttribute<MTRDoorLockSupportedOperatingModesAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeSupportedOperatingModesWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                         endpoint:(NSNumber *)endpoint
                                                            queue:(dispatch_queue_t)queue
                                                       completion:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completion
{
    auto * bridge = new MTRDoorLockSupportedOperatingModesAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(DoorLockSupportedOperatingModesAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::SupportedOperatingModes::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeDefaultConfigurationRegisterWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DoorLock::Attributes::DefaultConfigurationRegister::TypeInfo;
    return MTRReadAttribute<MTRDoorLockDefaultConfigurationRegisterAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeDefaultConfigurationRegisterWithParams:(MTRSubscribeParams * _Nonnull)params
                                         subscriptionEstablished:
                                             (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                   reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))reportHandler
{
    using TypeInfo = DoorLock::Attributes::DefaultConfigurationRegister::TypeInfo;
    MTRSubscribeAttribute<MTRDoorLockDefaultConfigurationRegisterAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeDefaultConfigurationRegisterWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                              endpoint:(NSNumber *)endpoint
                                                                 queue:(dispatch_queue_t)queue
                                                            completion:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completion
{
    auto * bridge = new MTRDoorLockDefaultConfigurationRegisterAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(DoorLockDefaultConfigurationRegisterAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::DefaultConfigurationRegister::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEnableLocalProgrammingWithCompletion:(void (^)(
                                                              NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DoorLock::Attributes::EnableLocalProgramming::TypeInfo;
    return MTRReadAttribute<MTRBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeEnableLocalProgrammingWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeEnableLocalProgrammingWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeEnableLocalProgrammingWithValue:(NSNumber * _Nonnull)value
                                               params:(MTRWriteParams * _Nullable)params
                                           completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = DoorLock::Attributes::EnableLocalProgramming::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.boolValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeEnableLocalProgrammingWithParams:(MTRSubscribeParams * _Nonnull)params
                                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = DoorLock::Attributes::EnableLocalProgramming::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEnableLocalProgrammingWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                                      completion:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::EnableLocalProgramming::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEnableOneTouchLockingWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DoorLock::Attributes::EnableOneTouchLocking::TypeInfo;
    return MTRReadAttribute<MTRBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeEnableOneTouchLockingWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeEnableOneTouchLockingWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeEnableOneTouchLockingWithValue:(NSNumber * _Nonnull)value
                                              params:(MTRWriteParams * _Nullable)params
                                          completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = DoorLock::Attributes::EnableOneTouchLocking::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.boolValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeEnableOneTouchLockingWithParams:(MTRSubscribeParams * _Nonnull)params
                                  subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = DoorLock::Attributes::EnableOneTouchLocking::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEnableOneTouchLockingWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                                     completion:
                                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::EnableOneTouchLocking::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEnableInsideStatusLEDWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DoorLock::Attributes::EnableInsideStatusLED::TypeInfo;
    return MTRReadAttribute<MTRBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeEnableInsideStatusLEDWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeEnableInsideStatusLEDWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeEnableInsideStatusLEDWithValue:(NSNumber * _Nonnull)value
                                              params:(MTRWriteParams * _Nullable)params
                                          completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = DoorLock::Attributes::EnableInsideStatusLED::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.boolValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeEnableInsideStatusLEDWithParams:(MTRSubscribeParams * _Nonnull)params
                                  subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = DoorLock::Attributes::EnableInsideStatusLED::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEnableInsideStatusLEDWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                                     completion:
                                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::EnableInsideStatusLED::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEnablePrivacyModeButtonWithCompletion:(void (^)(
                                                               NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DoorLock::Attributes::EnablePrivacyModeButton::TypeInfo;
    return MTRReadAttribute<MTRBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeEnablePrivacyModeButtonWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeEnablePrivacyModeButtonWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeEnablePrivacyModeButtonWithValue:(NSNumber * _Nonnull)value
                                                params:(MTRWriteParams * _Nullable)params
                                            completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = DoorLock::Attributes::EnablePrivacyModeButton::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.boolValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeEnablePrivacyModeButtonWithParams:(MTRSubscribeParams * _Nonnull)params
                                    subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = DoorLock::Attributes::EnablePrivacyModeButton::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEnablePrivacyModeButtonWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                         endpoint:(NSNumber *)endpoint
                                                            queue:(dispatch_queue_t)queue
                                                       completion:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::EnablePrivacyModeButton::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeLocalProgrammingFeaturesWithCompletion:(void (^)(
                                                                NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DoorLock::Attributes::LocalProgrammingFeatures::TypeInfo;
    return MTRReadAttribute<MTRDoorLockLocalProgrammingFeaturesAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeLocalProgrammingFeaturesWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeLocalProgrammingFeaturesWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeLocalProgrammingFeaturesWithValue:(NSNumber * _Nonnull)value
                                                 params:(MTRWriteParams * _Nullable)params
                                             completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = DoorLock::Attributes::LocalProgrammingFeatures::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = static_cast<std::remove_reference_t<decltype(cppValue)>>(value.unsignedCharValue);

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeLocalProgrammingFeaturesWithParams:(MTRSubscribeParams * _Nonnull)params
                                     subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = DoorLock::Attributes::LocalProgrammingFeatures::TypeInfo;
    MTRSubscribeAttribute<MTRDoorLockLocalProgrammingFeaturesAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeLocalProgrammingFeaturesWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                          endpoint:(NSNumber *)endpoint
                                                             queue:(dispatch_queue_t)queue
                                                        completion:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completion
{
    auto * bridge = new MTRDoorLockLocalProgrammingFeaturesAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(DoorLockLocalProgrammingFeaturesAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::LocalProgrammingFeatures::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeWrongCodeEntryLimitWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DoorLock::Attributes::WrongCodeEntryLimit::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeWrongCodeEntryLimitWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeWrongCodeEntryLimitWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeWrongCodeEntryLimitWithValue:(NSNumber * _Nonnull)value
                                            params:(MTRWriteParams * _Nullable)params
                                        completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = DoorLock::Attributes::WrongCodeEntryLimit::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeWrongCodeEntryLimitWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = DoorLock::Attributes::WrongCodeEntryLimit::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeWrongCodeEntryLimitWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::WrongCodeEntryLimit::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeUserCodeTemporaryDisableTimeWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DoorLock::Attributes::UserCodeTemporaryDisableTime::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeUserCodeTemporaryDisableTimeWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeUserCodeTemporaryDisableTimeWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeUserCodeTemporaryDisableTimeWithValue:(NSNumber * _Nonnull)value
                                                     params:(MTRWriteParams * _Nullable)params
                                                 completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = DoorLock::Attributes::UserCodeTemporaryDisableTime::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeUserCodeTemporaryDisableTimeWithParams:(MTRSubscribeParams * _Nonnull)params
                                         subscriptionEstablished:
                                             (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                   reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))reportHandler
{
    using TypeInfo = DoorLock::Attributes::UserCodeTemporaryDisableTime::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeUserCodeTemporaryDisableTimeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                              endpoint:(NSNumber *)endpoint
                                                                 queue:(dispatch_queue_t)queue
                                                            completion:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::UserCodeTemporaryDisableTime::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSendPINOverTheAirWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DoorLock::Attributes::SendPINOverTheAir::TypeInfo;
    return MTRReadAttribute<MTRBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeSendPINOverTheAirWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeSendPINOverTheAirWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeSendPINOverTheAirWithValue:(NSNumber * _Nonnull)value
                                          params:(MTRWriteParams * _Nullable)params
                                      completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = DoorLock::Attributes::SendPINOverTheAir::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.boolValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeSendPINOverTheAirWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = DoorLock::Attributes::SendPINOverTheAir::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeSendPINOverTheAirWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::SendPINOverTheAir::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRequirePINforRemoteOperationWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DoorLock::Attributes::RequirePINforRemoteOperation::TypeInfo;
    return MTRReadAttribute<MTRBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeRequirePINforRemoteOperationWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeRequirePINforRemoteOperationWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeRequirePINforRemoteOperationWithValue:(NSNumber * _Nonnull)value
                                                     params:(MTRWriteParams * _Nullable)params
                                                 completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = DoorLock::Attributes::RequirePINforRemoteOperation::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.boolValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeRequirePINforRemoteOperationWithParams:(MTRSubscribeParams * _Nonnull)params
                                         subscriptionEstablished:
                                             (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                   reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))reportHandler
{
    using TypeInfo = DoorLock::Attributes::RequirePINforRemoteOperation::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRequirePINforRemoteOperationWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                              endpoint:(NSNumber *)endpoint
                                                                 queue:(dispatch_queue_t)queue
                                                            completion:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::RequirePINforRemoteOperation::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeExpiringUserTimeoutWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DoorLock::Attributes::ExpiringUserTimeout::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeExpiringUserTimeoutWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeExpiringUserTimeoutWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeExpiringUserTimeoutWithValue:(NSNumber * _Nonnull)value
                                            params:(MTRWriteParams * _Nullable)params
                                        completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = DoorLock::Attributes::ExpiringUserTimeout::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeExpiringUserTimeoutWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = DoorLock::Attributes::ExpiringUserTimeout::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeExpiringUserTimeoutWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::ExpiringUserTimeout::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DoorLock::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRDoorLockGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = DoorLock::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRDoorLockGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRDoorLockGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(DoorLockGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DoorLock::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRDoorLockAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = DoorLock::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRDoorLockAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRDoorLockAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(DoorLockAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DoorLock::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRDoorLockEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = DoorLock::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRDoorLockEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRDoorLockEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(DoorLockEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DoorLock::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRDoorLockAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = DoorLock::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRDoorLockAttributeListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRDoorLockAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(DoorLockAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DoorLock::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = DoorLock::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = DoorLock::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = DoorLock::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterDoorLock (Deprecated)

- (void)lockDoorWithParams:(MTRDoorLockClusterLockDoorParams * _Nullable)params
         completionHandler:(MTRStatusCompletion)completionHandler
{
    [self lockDoorWithParams:params completion:completionHandler];
}
- (void)unlockDoorWithParams:(MTRDoorLockClusterUnlockDoorParams * _Nullable)params
           completionHandler:(MTRStatusCompletion)completionHandler
{
    [self unlockDoorWithParams:params completion:completionHandler];
}
- (void)unlockWithTimeoutWithParams:(MTRDoorLockClusterUnlockWithTimeoutParams *)params
                  completionHandler:(MTRStatusCompletion)completionHandler
{
    [self unlockWithTimeoutWithParams:params completion:completionHandler];
}
- (void)setWeekDayScheduleWithParams:(MTRDoorLockClusterSetWeekDayScheduleParams *)params
                   completionHandler:(MTRStatusCompletion)completionHandler
{
    [self setWeekDayScheduleWithParams:params completion:completionHandler];
}
- (void)getWeekDayScheduleWithParams:(MTRDoorLockClusterGetWeekDayScheduleParams *)params
                   completionHandler:(void (^)(MTRDoorLockClusterGetWeekDayScheduleResponseParams * _Nullable data,
                                         NSError * _Nullable error))completionHandler
{
    [self getWeekDayScheduleWithParams:params
                            completion:^(
                                MTRDoorLockClusterGetWeekDayScheduleResponseParams * _Nullable data, NSError * _Nullable error) {
                                // Cast is safe because subclass does not add any selectors.
                                completionHandler(static_cast<MTRDoorLockClusterGetWeekDayScheduleResponseParams *>(data), error);
                            }];
}
- (void)clearWeekDayScheduleWithParams:(MTRDoorLockClusterClearWeekDayScheduleParams *)params
                     completionHandler:(MTRStatusCompletion)completionHandler
{
    [self clearWeekDayScheduleWithParams:params completion:completionHandler];
}
- (void)setYearDayScheduleWithParams:(MTRDoorLockClusterSetYearDayScheduleParams *)params
                   completionHandler:(MTRStatusCompletion)completionHandler
{
    [self setYearDayScheduleWithParams:params completion:completionHandler];
}
- (void)getYearDayScheduleWithParams:(MTRDoorLockClusterGetYearDayScheduleParams *)params
                   completionHandler:(void (^)(MTRDoorLockClusterGetYearDayScheduleResponseParams * _Nullable data,
                                         NSError * _Nullable error))completionHandler
{
    [self getYearDayScheduleWithParams:params
                            completion:^(
                                MTRDoorLockClusterGetYearDayScheduleResponseParams * _Nullable data, NSError * _Nullable error) {
                                // Cast is safe because subclass does not add any selectors.
                                completionHandler(static_cast<MTRDoorLockClusterGetYearDayScheduleResponseParams *>(data), error);
                            }];
}
- (void)clearYearDayScheduleWithParams:(MTRDoorLockClusterClearYearDayScheduleParams *)params
                     completionHandler:(MTRStatusCompletion)completionHandler
{
    [self clearYearDayScheduleWithParams:params completion:completionHandler];
}
- (void)setHolidayScheduleWithParams:(MTRDoorLockClusterSetHolidayScheduleParams *)params
                   completionHandler:(MTRStatusCompletion)completionHandler
{
    [self setHolidayScheduleWithParams:params completion:completionHandler];
}
- (void)getHolidayScheduleWithParams:(MTRDoorLockClusterGetHolidayScheduleParams *)params
                   completionHandler:(void (^)(MTRDoorLockClusterGetHolidayScheduleResponseParams * _Nullable data,
                                         NSError * _Nullable error))completionHandler
{
    [self getHolidayScheduleWithParams:params
                            completion:^(
                                MTRDoorLockClusterGetHolidayScheduleResponseParams * _Nullable data, NSError * _Nullable error) {
                                // Cast is safe because subclass does not add any selectors.
                                completionHandler(static_cast<MTRDoorLockClusterGetHolidayScheduleResponseParams *>(data), error);
                            }];
}
- (void)clearHolidayScheduleWithParams:(MTRDoorLockClusterClearHolidayScheduleParams *)params
                     completionHandler:(MTRStatusCompletion)completionHandler
{
    [self clearHolidayScheduleWithParams:params completion:completionHandler];
}
- (void)setUserWithParams:(MTRDoorLockClusterSetUserParams *)params completionHandler:(MTRStatusCompletion)completionHandler
{
    [self setUserWithParams:params completion:completionHandler];
}
- (void)getUserWithParams:(MTRDoorLockClusterGetUserParams *)params
        completionHandler:
            (void (^)(MTRDoorLockClusterGetUserResponseParams * _Nullable data, NSError * _Nullable error))completionHandler
{
    [self getUserWithParams:params
                 completion:^(MTRDoorLockClusterGetUserResponseParams * _Nullable data, NSError * _Nullable error) {
                     // Cast is safe because subclass does not add any selectors.
                     completionHandler(static_cast<MTRDoorLockClusterGetUserResponseParams *>(data), error);
                 }];
}
- (void)clearUserWithParams:(MTRDoorLockClusterClearUserParams *)params completionHandler:(MTRStatusCompletion)completionHandler
{
    [self clearUserWithParams:params completion:completionHandler];
}
- (void)setCredentialWithParams:(MTRDoorLockClusterSetCredentialParams *)params
              completionHandler:(void (^)(MTRDoorLockClusterSetCredentialResponseParams * _Nullable data,
                                    NSError * _Nullable error))completionHandler
{
    [self setCredentialWithParams:params
                       completion:^(MTRDoorLockClusterSetCredentialResponseParams * _Nullable data, NSError * _Nullable error) {
                           // Cast is safe because subclass does not add any selectors.
                           completionHandler(static_cast<MTRDoorLockClusterSetCredentialResponseParams *>(data), error);
                       }];
}
- (void)getCredentialStatusWithParams:(MTRDoorLockClusterGetCredentialStatusParams *)params
                    completionHandler:(void (^)(MTRDoorLockClusterGetCredentialStatusResponseParams * _Nullable data,
                                          NSError * _Nullable error))completionHandler
{
    [self getCredentialStatusWithParams:params
                             completion:^(
                                 MTRDoorLockClusterGetCredentialStatusResponseParams * _Nullable data, NSError * _Nullable error) {
                                 // Cast is safe because subclass does not add any selectors.
                                 completionHandler(static_cast<MTRDoorLockClusterGetCredentialStatusResponseParams *>(data), error);
                             }];
}
- (void)clearCredentialWithParams:(MTRDoorLockClusterClearCredentialParams *)params
                completionHandler:(MTRStatusCompletion)completionHandler
{
    [self clearCredentialWithParams:params completion:completionHandler];
}
- (void)unboltDoorWithParams:(MTRDoorLockClusterUnboltDoorParams * _Nullable)params
           completionHandler:(MTRStatusCompletion)completionHandler
{
    [self unboltDoorWithParams:params completion:completionHandler];
}

- (void)readAttributeLockStateWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLockStateWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeLockStateWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeLockStateWithParams:subscribeParams
                        subscriptionEstablished:subscriptionEstablishedHandler
                                  reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                      // Cast is safe because subclass does not add any selectors.
                                      reportHandler(static_cast<NSNumber *>(value), error);
                                  }];
}
+ (void)readAttributeLockStateWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLockStateWithClusterStateCache:attributeCacheContainer.realContainer
                                             endpoint:endpoint
                                                queue:queue
                                           completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               completionHandler(static_cast<NSNumber *>(value), error);
                                           }];
}

- (void)readAttributeLockTypeWithCompletionHandler:(void (^)(
                                                       NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLockTypeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeLockTypeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeLockTypeWithParams:subscribeParams
                       subscriptionEstablished:subscriptionEstablishedHandler
                                 reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                     // Cast is safe because subclass does not add any selectors.
                                     reportHandler(static_cast<NSNumber *>(value), error);
                                 }];
}
+ (void)readAttributeLockTypeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLockTypeWithClusterStateCache:attributeCacheContainer.realContainer
                                            endpoint:endpoint
                                               queue:queue
                                          completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              completionHandler(static_cast<NSNumber *>(value), error);
                                          }];
}

- (void)readAttributeActuatorEnabledWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeActuatorEnabledWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeActuatorEnabledWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeActuatorEnabledWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeActuatorEnabledWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeActuatorEnabledWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (void)readAttributeDoorStateWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDoorStateWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeDoorStateWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeDoorStateWithParams:subscribeParams
                        subscriptionEstablished:subscriptionEstablishedHandler
                                  reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                      // Cast is safe because subclass does not add any selectors.
                                      reportHandler(static_cast<NSNumber *>(value), error);
                                  }];
}
+ (void)readAttributeDoorStateWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDoorStateWithClusterStateCache:attributeCacheContainer.realContainer
                                             endpoint:endpoint
                                                queue:queue
                                           completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               completionHandler(static_cast<NSNumber *>(value), error);
                                           }];
}

- (void)readAttributeDoorOpenEventsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeDoorOpenEventsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeDoorOpenEventsWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeDoorOpenEventsWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeDoorOpenEventsWithValue:(NSNumber * _Nonnull)value
                                       params:(MTRWriteParams * _Nullable)params
                            completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeDoorOpenEventsWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeDoorOpenEventsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeDoorOpenEventsWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSNumber *>(value), error);
                                       }];
}
+ (void)readAttributeDoorOpenEventsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDoorOpenEventsWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSNumber *>(value), error);
                                                }];
}

- (void)readAttributeDoorClosedEventsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeDoorClosedEventsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeDoorClosedEventsWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeDoorClosedEventsWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeDoorClosedEventsWithValue:(NSNumber * _Nonnull)value
                                         params:(MTRWriteParams * _Nullable)params
                              completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeDoorClosedEventsWithValue:value params:params completion:completionHandler];
}
- (void)
    subscribeAttributeDoorClosedEventsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeDoorClosedEventsWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributeDoorClosedEventsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDoorClosedEventsWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeOpenPeriodWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOpenPeriodWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeOpenPeriodWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeOpenPeriodWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeOpenPeriodWithValue:(NSNumber * _Nonnull)value
                                   params:(MTRWriteParams * _Nullable)params
                        completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeOpenPeriodWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeOpenPeriodWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeOpenPeriodWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeOpenPeriodWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOpenPeriodWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeNumberOfTotalUsersSupportedWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))completionHandler
{
    [self readAttributeNumberOfTotalUsersSupportedWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeNumberOfTotalUsersSupportedWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                                              params:(MTRSubscribeParams * _Nullable)params
                                             subscriptionEstablished:
                                                 (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                       reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNumberOfTotalUsersSupportedWithParams:subscribeParams
                                          subscriptionEstablished:subscriptionEstablishedHandler
                                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                        // Cast is safe because subclass does not add any selectors.
                                                        reportHandler(static_cast<NSNumber *>(value), error);
                                                    }];
}
+ (void)readAttributeNumberOfTotalUsersSupportedWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                          endpoint:(NSNumber *)endpoint
                                                             queue:(dispatch_queue_t)queue
                                                 completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completionHandler
{
    [self readAttributeNumberOfTotalUsersSupportedWithClusterStateCache:attributeCacheContainer.realContainer
                                                               endpoint:endpoint
                                                                  queue:queue
                                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                 // Cast is safe because subclass does not add any selectors.
                                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                                             }];
}

- (void)readAttributeNumberOfPINUsersSupportedWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    [self readAttributeNumberOfPINUsersSupportedWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeNumberOfPINUsersSupportedWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                                            params:(MTRSubscribeParams * _Nullable)params
                                           subscriptionEstablished:
                                               (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                     reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNumberOfPINUsersSupportedWithParams:subscribeParams
                                        subscriptionEstablished:subscriptionEstablishedHandler
                                                  reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      reportHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}
+ (void)readAttributeNumberOfPINUsersSupportedWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                               completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    [self readAttributeNumberOfPINUsersSupportedWithClusterStateCache:attributeCacheContainer.realContainer
                                                             endpoint:endpoint
                                                                queue:queue
                                                           completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                               // Cast is safe because subclass does not add any selectors.
                                                               completionHandler(static_cast<NSNumber *>(value), error);
                                                           }];
}

- (void)readAttributeNumberOfRFIDUsersSupportedWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    [self readAttributeNumberOfRFIDUsersSupportedWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeNumberOfRFIDUsersSupportedWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                                             params:(MTRSubscribeParams * _Nullable)params
                                            subscriptionEstablished:
                                                (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                      reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNumberOfRFIDUsersSupportedWithParams:subscribeParams
                                         subscriptionEstablished:subscriptionEstablishedHandler
                                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       reportHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}
+ (void)readAttributeNumberOfRFIDUsersSupportedWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                         endpoint:(NSNumber *)endpoint
                                                            queue:(dispatch_queue_t)queue
                                                completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    [self readAttributeNumberOfRFIDUsersSupportedWithClusterStateCache:attributeCacheContainer.realContainer
                                                              endpoint:endpoint
                                                                 queue:queue
                                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                // Cast is safe because subclass does not add any selectors.
                                                                completionHandler(static_cast<NSNumber *>(value), error);
                                                            }];
}

- (void)readAttributeNumberOfWeekDaySchedulesSupportedPerUserWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                       NSError * _Nullable error))completionHandler
{
    [self readAttributeNumberOfWeekDaySchedulesSupportedPerUserWithCompletion:^(
        NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeNumberOfWeekDaySchedulesSupportedPerUserWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                           params:(MTRSubscribeParams * _Nullable)params
                                                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)
                                                                                      subscriptionEstablishedHandler
                                                                    reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                      NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNumberOfWeekDaySchedulesSupportedPerUserWithParams:subscribeParams
                                                       subscriptionEstablished:subscriptionEstablishedHandler
                                                                 reportHandler:^(
                                                                     NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                     // Cast is safe because subclass does not add any selectors.
                                                                     reportHandler(static_cast<NSNumber *>(value), error);
                                                                 }];
}
+ (void)readAttributeNumberOfWeekDaySchedulesSupportedPerUserWithAttributeCache:
            (MTRAttributeCacheContainer *)attributeCacheContainer
                                                                       endpoint:(NSNumber *)endpoint
                                                                          queue:(dispatch_queue_t)queue
                                                              completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                    NSError * _Nullable error))completionHandler
{
    [self readAttributeNumberOfWeekDaySchedulesSupportedPerUserWithClusterStateCache:attributeCacheContainer.realContainer
                                                                            endpoint:endpoint
                                                                               queue:queue
                                                                          completion:^(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error) {
                                                                              // Cast is safe because subclass does not add any
                                                                              // selectors.
                                                                              completionHandler(
                                                                                  static_cast<NSNumber *>(value), error);
                                                                          }];
}

- (void)readAttributeNumberOfYearDaySchedulesSupportedPerUserWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                       NSError * _Nullable error))completionHandler
{
    [self readAttributeNumberOfYearDaySchedulesSupportedPerUserWithCompletion:^(
        NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeNumberOfYearDaySchedulesSupportedPerUserWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                           params:(MTRSubscribeParams * _Nullable)params
                                                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)
                                                                                      subscriptionEstablishedHandler
                                                                    reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                      NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNumberOfYearDaySchedulesSupportedPerUserWithParams:subscribeParams
                                                       subscriptionEstablished:subscriptionEstablishedHandler
                                                                 reportHandler:^(
                                                                     NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                     // Cast is safe because subclass does not add any selectors.
                                                                     reportHandler(static_cast<NSNumber *>(value), error);
                                                                 }];
}
+ (void)readAttributeNumberOfYearDaySchedulesSupportedPerUserWithAttributeCache:
            (MTRAttributeCacheContainer *)attributeCacheContainer
                                                                       endpoint:(NSNumber *)endpoint
                                                                          queue:(dispatch_queue_t)queue
                                                              completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                    NSError * _Nullable error))completionHandler
{
    [self readAttributeNumberOfYearDaySchedulesSupportedPerUserWithClusterStateCache:attributeCacheContainer.realContainer
                                                                            endpoint:endpoint
                                                                               queue:queue
                                                                          completion:^(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error) {
                                                                              // Cast is safe because subclass does not add any
                                                                              // selectors.
                                                                              completionHandler(
                                                                                  static_cast<NSNumber *>(value), error);
                                                                          }];
}

- (void)readAttributeNumberOfHolidaySchedulesSupportedWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeNumberOfHolidaySchedulesSupportedWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeNumberOfHolidaySchedulesSupportedWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                    params:(MTRSubscribeParams * _Nullable)params
                                                   subscriptionEstablished:
                                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                             reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                               NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNumberOfHolidaySchedulesSupportedWithParams:subscribeParams
                                                subscriptionEstablished:subscriptionEstablishedHandler
                                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                              // Cast is safe because subclass does not add any selectors.
                                                              reportHandler(static_cast<NSNumber *>(value), error);
                                                          }];
}
+ (void)readAttributeNumberOfHolidaySchedulesSupportedWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                                endpoint:(NSNumber *)endpoint
                                                                   queue:(dispatch_queue_t)queue
                                                       completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeNumberOfHolidaySchedulesSupportedWithClusterStateCache:attributeCacheContainer.realContainer
                                                                     endpoint:endpoint
                                                                        queue:queue
                                                                   completion:^(
                                                                       NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                       // Cast is safe because subclass does not add any selectors.
                                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                                   }];
}

- (void)readAttributeMaxPINCodeLengthWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxPINCodeLengthWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)
    subscribeAttributeMaxPINCodeLengthWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMaxPINCodeLengthWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributeMaxPINCodeLengthWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxPINCodeLengthWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeMinPINCodeLengthWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeMinPINCodeLengthWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)
    subscribeAttributeMinPINCodeLengthWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMinPINCodeLengthWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributeMinPINCodeLengthWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMinPINCodeLengthWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeMaxRFIDCodeLengthWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxRFIDCodeLengthWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeMaxRFIDCodeLengthWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMaxRFIDCodeLengthWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSNumber *>(value), error);
                                          }];
}
+ (void)readAttributeMaxRFIDCodeLengthWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxRFIDCodeLengthWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}

- (void)readAttributeMinRFIDCodeLengthWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeMinRFIDCodeLengthWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeMinRFIDCodeLengthWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMinRFIDCodeLengthWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSNumber *>(value), error);
                                          }];
}
+ (void)readAttributeMinRFIDCodeLengthWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMinRFIDCodeLengthWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}

- (void)readAttributeCredentialRulesSupportWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    [self readAttributeCredentialRulesSupportWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeCredentialRulesSupportWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                                         params:(MTRSubscribeParams * _Nullable)params
                                        subscriptionEstablished:
                                            (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeCredentialRulesSupportWithParams:subscribeParams
                                     subscriptionEstablished:subscriptionEstablishedHandler
                                               reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   reportHandler(static_cast<NSNumber *>(value), error);
                                               }];
}
+ (void)readAttributeCredentialRulesSupportWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                            completionHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCredentialRulesSupportWithClusterStateCache:attributeCacheContainer.realContainer
                                                          endpoint:endpoint
                                                             queue:queue
                                                        completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                            // Cast is safe because subclass does not add any selectors.
                                                            completionHandler(static_cast<NSNumber *>(value), error);
                                                        }];
}

- (void)readAttributeNumberOfCredentialsSupportedPerUserWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeNumberOfCredentialsSupportedPerUserWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeNumberOfCredentialsSupportedPerUserWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                      params:(MTRSubscribeParams * _Nullable)params
                                                     subscriptionEstablished:
                                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                               reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                 NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNumberOfCredentialsSupportedPerUserWithParams:subscribeParams
                                                  subscriptionEstablished:subscriptionEstablishedHandler
                                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                // Cast is safe because subclass does not add any selectors.
                                                                reportHandler(static_cast<NSNumber *>(value), error);
                                                            }];
}
+ (void)readAttributeNumberOfCredentialsSupportedPerUserWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                                  endpoint:(NSNumber *)endpoint
                                                                     queue:(dispatch_queue_t)queue
                                                         completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeNumberOfCredentialsSupportedPerUserWithClusterStateCache:attributeCacheContainer.realContainer
                                                                       endpoint:endpoint
                                                                          queue:queue
                                                                     completion:^(
                                                                         NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                         // Cast is safe because subclass does not add any
                                                                         // selectors.
                                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                                     }];
}

- (void)readAttributeLanguageWithCompletionHandler:(void (^)(
                                                       NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLanguageWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)writeAttributeLanguageWithValue:(NSString * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeLanguageWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeLanguageWithValue:(NSString * _Nonnull)value
                                 params:(MTRWriteParams * _Nullable)params
                      completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeLanguageWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeLanguageWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeLanguageWithParams:subscribeParams
                       subscriptionEstablished:subscriptionEstablishedHandler
                                 reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                     // Cast is safe because subclass does not add any selectors.
                                     reportHandler(static_cast<NSString *>(value), error);
                                 }];
}
+ (void)readAttributeLanguageWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLanguageWithClusterStateCache:attributeCacheContainer.realContainer
                                            endpoint:endpoint
                                               queue:queue
                                          completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              completionHandler(static_cast<NSString *>(value), error);
                                          }];
}

- (void)readAttributeLEDSettingsWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLEDSettingsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeLEDSettingsWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeLEDSettingsWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeLEDSettingsWithValue:(NSNumber * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                         completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeLEDSettingsWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeLEDSettingsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeLEDSettingsWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSNumber *>(value), error);
                                    }];
}
+ (void)readAttributeLEDSettingsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLEDSettingsWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                             }];
}

- (void)readAttributeAutoRelockTimeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeAutoRelockTimeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeAutoRelockTimeWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeAutoRelockTimeWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeAutoRelockTimeWithValue:(NSNumber * _Nonnull)value
                                       params:(MTRWriteParams * _Nullable)params
                            completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeAutoRelockTimeWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeAutoRelockTimeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAutoRelockTimeWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSNumber *>(value), error);
                                       }];
}
+ (void)readAttributeAutoRelockTimeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAutoRelockTimeWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSNumber *>(value), error);
                                                }];
}

- (void)readAttributeSoundVolumeWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSoundVolumeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeSoundVolumeWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeSoundVolumeWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeSoundVolumeWithValue:(NSNumber * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                         completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeSoundVolumeWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeSoundVolumeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeSoundVolumeWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSNumber *>(value), error);
                                    }];
}
+ (void)readAttributeSoundVolumeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSoundVolumeWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                             }];
}

- (void)readAttributeOperatingModeWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOperatingModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeOperatingModeWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeOperatingModeWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeOperatingModeWithValue:(NSNumber * _Nonnull)value
                                      params:(MTRWriteParams * _Nullable)params
                           completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeOperatingModeWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeOperatingModeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeOperatingModeWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributeOperatingModeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOperatingModeWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributeSupportedOperatingModesWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    [self readAttributeSupportedOperatingModesWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeSupportedOperatingModesWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                                          params:(MTRSubscribeParams * _Nullable)params
                                         subscriptionEstablished:
                                             (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                   reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeSupportedOperatingModesWithParams:subscribeParams
                                      subscriptionEstablished:subscriptionEstablishedHandler
                                                reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    reportHandler(static_cast<NSNumber *>(value), error);
                                                }];
}
+ (void)readAttributeSupportedOperatingModesWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                             completionHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSupportedOperatingModesWithClusterStateCache:attributeCacheContainer.realContainer
                                                           endpoint:endpoint
                                                              queue:queue
                                                         completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                             // Cast is safe because subclass does not add any selectors.
                                                             completionHandler(static_cast<NSNumber *>(value), error);
                                                         }];
}

- (void)readAttributeDefaultConfigurationRegisterWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completionHandler
{
    [self readAttributeDefaultConfigurationRegisterWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeDefaultConfigurationRegisterWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                                               params:(MTRSubscribeParams * _Nullable)params
                                              subscriptionEstablished:
                                                  (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                        reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeDefaultConfigurationRegisterWithParams:subscribeParams
                                           subscriptionEstablished:subscriptionEstablishedHandler
                                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         reportHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}
+ (void)readAttributeDefaultConfigurationRegisterWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                           endpoint:(NSNumber *)endpoint
                                                              queue:(dispatch_queue_t)queue
                                                  completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    [self readAttributeDefaultConfigurationRegisterWithClusterStateCache:attributeCacheContainer.realContainer
                                                                endpoint:endpoint
                                                                   queue:queue
                                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                  // Cast is safe because subclass does not add any selectors.
                                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                                              }];
}

- (void)readAttributeEnableLocalProgrammingWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    [self readAttributeEnableLocalProgrammingWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeEnableLocalProgrammingWithValue:(NSNumber * _Nonnull)value
                                    completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeEnableLocalProgrammingWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeEnableLocalProgrammingWithValue:(NSNumber * _Nonnull)value
                                               params:(MTRWriteParams * _Nullable)params
                                    completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeEnableLocalProgrammingWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeEnableLocalProgrammingWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                                         params:(MTRSubscribeParams * _Nullable)params
                                        subscriptionEstablished:
                                            (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeEnableLocalProgrammingWithParams:subscribeParams
                                     subscriptionEstablished:subscriptionEstablishedHandler
                                               reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   reportHandler(static_cast<NSNumber *>(value), error);
                                               }];
}
+ (void)readAttributeEnableLocalProgrammingWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                            completionHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeEnableLocalProgrammingWithClusterStateCache:attributeCacheContainer.realContainer
                                                          endpoint:endpoint
                                                             queue:queue
                                                        completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                            // Cast is safe because subclass does not add any selectors.
                                                            completionHandler(static_cast<NSNumber *>(value), error);
                                                        }];
}

- (void)readAttributeEnableOneTouchLockingWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    [self readAttributeEnableOneTouchLockingWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeEnableOneTouchLockingWithValue:(NSNumber * _Nonnull)value
                                   completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeEnableOneTouchLockingWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeEnableOneTouchLockingWithValue:(NSNumber * _Nonnull)value
                                              params:(MTRWriteParams * _Nullable)params
                                   completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeEnableOneTouchLockingWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeEnableOneTouchLockingWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeEnableOneTouchLockingWithParams:subscribeParams
                                    subscriptionEstablished:subscriptionEstablishedHandler
                                              reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  reportHandler(static_cast<NSNumber *>(value), error);
                                              }];
}
+ (void)readAttributeEnableOneTouchLockingWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeEnableOneTouchLockingWithClusterStateCache:attributeCacheContainer.realContainer
                                                         endpoint:endpoint
                                                            queue:queue
                                                       completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                           // Cast is safe because subclass does not add any selectors.
                                                           completionHandler(static_cast<NSNumber *>(value), error);
                                                       }];
}

- (void)readAttributeEnableInsideStatusLEDWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    [self readAttributeEnableInsideStatusLEDWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeEnableInsideStatusLEDWithValue:(NSNumber * _Nonnull)value
                                   completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeEnableInsideStatusLEDWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeEnableInsideStatusLEDWithValue:(NSNumber * _Nonnull)value
                                              params:(MTRWriteParams * _Nullable)params
                                   completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeEnableInsideStatusLEDWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeEnableInsideStatusLEDWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeEnableInsideStatusLEDWithParams:subscribeParams
                                    subscriptionEstablished:subscriptionEstablishedHandler
                                              reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  reportHandler(static_cast<NSNumber *>(value), error);
                                              }];
}
+ (void)readAttributeEnableInsideStatusLEDWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeEnableInsideStatusLEDWithClusterStateCache:attributeCacheContainer.realContainer
                                                         endpoint:endpoint
                                                            queue:queue
                                                       completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                           // Cast is safe because subclass does not add any selectors.
                                                           completionHandler(static_cast<NSNumber *>(value), error);
                                                       }];
}

- (void)readAttributeEnablePrivacyModeButtonWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    [self readAttributeEnablePrivacyModeButtonWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeEnablePrivacyModeButtonWithValue:(NSNumber * _Nonnull)value
                                     completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeEnablePrivacyModeButtonWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeEnablePrivacyModeButtonWithValue:(NSNumber * _Nonnull)value
                                                params:(MTRWriteParams * _Nullable)params
                                     completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeEnablePrivacyModeButtonWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeEnablePrivacyModeButtonWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                                          params:(MTRSubscribeParams * _Nullable)params
                                         subscriptionEstablished:
                                             (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                   reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeEnablePrivacyModeButtonWithParams:subscribeParams
                                      subscriptionEstablished:subscriptionEstablishedHandler
                                                reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    reportHandler(static_cast<NSNumber *>(value), error);
                                                }];
}
+ (void)readAttributeEnablePrivacyModeButtonWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                             completionHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeEnablePrivacyModeButtonWithClusterStateCache:attributeCacheContainer.realContainer
                                                           endpoint:endpoint
                                                              queue:queue
                                                         completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                             // Cast is safe because subclass does not add any selectors.
                                                             completionHandler(static_cast<NSNumber *>(value), error);
                                                         }];
}

- (void)readAttributeLocalProgrammingFeaturesWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completionHandler
{
    [self readAttributeLocalProgrammingFeaturesWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeLocalProgrammingFeaturesWithValue:(NSNumber * _Nonnull)value
                                      completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeLocalProgrammingFeaturesWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeLocalProgrammingFeaturesWithValue:(NSNumber * _Nonnull)value
                                                 params:(MTRWriteParams * _Nullable)params
                                      completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeLocalProgrammingFeaturesWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeLocalProgrammingFeaturesWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                                           params:(MTRSubscribeParams * _Nullable)params
                                          subscriptionEstablished:
                                              (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                    reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeLocalProgrammingFeaturesWithParams:subscribeParams
                                       subscriptionEstablished:subscriptionEstablishedHandler
                                                 reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     reportHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}
+ (void)readAttributeLocalProgrammingFeaturesWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                              completionHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLocalProgrammingFeaturesWithClusterStateCache:attributeCacheContainer.realContainer
                                                            endpoint:endpoint
                                                               queue:queue
                                                          completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                              // Cast is safe because subclass does not add any selectors.
                                                              completionHandler(static_cast<NSNumber *>(value), error);
                                                          }];
}

- (void)readAttributeWrongCodeEntryLimitWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeWrongCodeEntryLimitWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeWrongCodeEntryLimitWithValue:(NSNumber * _Nonnull)value
                                 completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeWrongCodeEntryLimitWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeWrongCodeEntryLimitWithValue:(NSNumber * _Nonnull)value
                                            params:(MTRWriteParams * _Nullable)params
                                 completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeWrongCodeEntryLimitWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeWrongCodeEntryLimitWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeWrongCodeEntryLimitWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSNumber *>(value), error);
                                            }];
}
+ (void)readAttributeWrongCodeEntryLimitWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeWrongCodeEntryLimitWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}

- (void)readAttributeUserCodeTemporaryDisableTimeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completionHandler
{
    [self readAttributeUserCodeTemporaryDisableTimeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeUserCodeTemporaryDisableTimeWithValue:(NSNumber * _Nonnull)value
                                          completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeUserCodeTemporaryDisableTimeWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeUserCodeTemporaryDisableTimeWithValue:(NSNumber * _Nonnull)value
                                                     params:(MTRWriteParams * _Nullable)params
                                          completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeUserCodeTemporaryDisableTimeWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeUserCodeTemporaryDisableTimeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                                               params:(MTRSubscribeParams * _Nullable)params
                                              subscriptionEstablished:
                                                  (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                        reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeUserCodeTemporaryDisableTimeWithParams:subscribeParams
                                           subscriptionEstablished:subscriptionEstablishedHandler
                                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         reportHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}
+ (void)readAttributeUserCodeTemporaryDisableTimeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                           endpoint:(NSNumber *)endpoint
                                                              queue:(dispatch_queue_t)queue
                                                  completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    [self readAttributeUserCodeTemporaryDisableTimeWithClusterStateCache:attributeCacheContainer.realContainer
                                                                endpoint:endpoint
                                                                   queue:queue
                                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                  // Cast is safe because subclass does not add any selectors.
                                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                                              }];
}

- (void)readAttributeSendPINOverTheAirWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeSendPINOverTheAirWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeSendPINOverTheAirWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeSendPINOverTheAirWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeSendPINOverTheAirWithValue:(NSNumber * _Nonnull)value
                                          params:(MTRWriteParams * _Nullable)params
                               completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeSendPINOverTheAirWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeSendPINOverTheAirWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeSendPINOverTheAirWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSNumber *>(value), error);
                                          }];
}
+ (void)readAttributeSendPINOverTheAirWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSendPINOverTheAirWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}

- (void)readAttributeRequirePINforRemoteOperationWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completionHandler
{
    [self readAttributeRequirePINforRemoteOperationWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeRequirePINforRemoteOperationWithValue:(NSNumber * _Nonnull)value
                                          completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeRequirePINforRemoteOperationWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeRequirePINforRemoteOperationWithValue:(NSNumber * _Nonnull)value
                                                     params:(MTRWriteParams * _Nullable)params
                                          completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeRequirePINforRemoteOperationWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeRequirePINforRemoteOperationWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                                               params:(MTRSubscribeParams * _Nullable)params
                                              subscriptionEstablished:
                                                  (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                        reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRequirePINforRemoteOperationWithParams:subscribeParams
                                           subscriptionEstablished:subscriptionEstablishedHandler
                                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         reportHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}
+ (void)readAttributeRequirePINforRemoteOperationWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                           endpoint:(NSNumber *)endpoint
                                                              queue:(dispatch_queue_t)queue
                                                  completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    [self readAttributeRequirePINforRemoteOperationWithClusterStateCache:attributeCacheContainer.realContainer
                                                                endpoint:endpoint
                                                                   queue:queue
                                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                  // Cast is safe because subclass does not add any selectors.
                                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                                              }];
}

- (void)readAttributeExpiringUserTimeoutWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeExpiringUserTimeoutWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeExpiringUserTimeoutWithValue:(NSNumber * _Nonnull)value
                                 completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeExpiringUserTimeoutWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeExpiringUserTimeoutWithValue:(NSNumber * _Nonnull)value
                                            params:(MTRWriteParams * _Nullable)params
                                 completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeExpiringUserTimeoutWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeExpiringUserTimeoutWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeExpiringUserTimeoutWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSNumber *>(value), error);
                                            }];
}
+ (void)readAttributeExpiringUserTimeoutWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeExpiringUserTimeoutWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterWindowCovering

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)upOrOpenWithCompletion:(MTRStatusCompletion)completion
{
    [self upOrOpenWithParams:nil completion:completion];
}
- (void)upOrOpenWithParams:(MTRWindowCoveringClusterUpOrOpenParams * _Nullable)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            WindowCovering::Commands::UpOrOpen::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)downOrCloseWithCompletion:(MTRStatusCompletion)completion
{
    [self downOrCloseWithParams:nil completion:completion];
}
- (void)downOrCloseWithParams:(MTRWindowCoveringClusterDownOrCloseParams * _Nullable)params
                   completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            WindowCovering::Commands::DownOrClose::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)stopMotionWithCompletion:(MTRStatusCompletion)completion
{
    [self stopMotionWithParams:nil completion:completion];
}
- (void)stopMotionWithParams:(MTRWindowCoveringClusterStopMotionParams * _Nullable)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            WindowCovering::Commands::StopMotion::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)goToLiftValueWithParams:(MTRWindowCoveringClusterGoToLiftValueParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            WindowCovering::Commands::GoToLiftValue::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.liftValue = params.liftValue.unsignedShortValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)goToLiftPercentageWithParams:(MTRWindowCoveringClusterGoToLiftPercentageParams *)params
                          completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            WindowCovering::Commands::GoToLiftPercentage::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.liftPercent100thsValue = params.liftPercent100thsValue.unsignedShortValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)goToTiltValueWithParams:(MTRWindowCoveringClusterGoToTiltValueParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            WindowCovering::Commands::GoToTiltValue::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.tiltValue = params.tiltValue.unsignedShortValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)goToTiltPercentageWithParams:(MTRWindowCoveringClusterGoToTiltPercentageParams *)params
                          completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            WindowCovering::Commands::GoToTiltPercentage::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.tiltPercent100thsValue = params.tiltPercent100thsValue.unsignedShortValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeTypeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WindowCovering::Attributes::Type::TypeInfo;
    return MTRReadAttribute<MTRWindowCoveringClusterTypeAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeTypeWithParams:(MTRSubscribeParams * _Nonnull)params
                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                           reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WindowCovering::Attributes::Type::TypeInfo;
    MTRSubscribeAttribute<MTRWindowCoveringClusterTypeAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeTypeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                      endpoint:(NSNumber *)endpoint
                                         queue:(dispatch_queue_t)queue
                                    completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRWindowCoveringClusterTypeAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(WindowCoveringClusterTypeAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WindowCovering::Attributes::Type::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePhysicalClosedLimitLiftWithCompletion:(void (^)(
                                                               NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WindowCovering::Attributes::PhysicalClosedLimitLift::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePhysicalClosedLimitLiftWithParams:(MTRSubscribeParams * _Nonnull)params
                                    subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WindowCovering::Attributes::PhysicalClosedLimitLift::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePhysicalClosedLimitLiftWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                         endpoint:(NSNumber *)endpoint
                                                            queue:(dispatch_queue_t)queue
                                                       completion:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WindowCovering::Attributes::PhysicalClosedLimitLift::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePhysicalClosedLimitTiltWithCompletion:(void (^)(
                                                               NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WindowCovering::Attributes::PhysicalClosedLimitTilt::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePhysicalClosedLimitTiltWithParams:(MTRSubscribeParams * _Nonnull)params
                                    subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WindowCovering::Attributes::PhysicalClosedLimitTilt::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePhysicalClosedLimitTiltWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                         endpoint:(NSNumber *)endpoint
                                                            queue:(dispatch_queue_t)queue
                                                       completion:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WindowCovering::Attributes::PhysicalClosedLimitTilt::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCurrentPositionLiftWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WindowCovering::Attributes::CurrentPositionLift::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeCurrentPositionLiftWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WindowCovering::Attributes::CurrentPositionLift::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeCurrentPositionLiftWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WindowCovering::Attributes::CurrentPositionLift::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCurrentPositionTiltWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WindowCovering::Attributes::CurrentPositionTilt::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeCurrentPositionTiltWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WindowCovering::Attributes::CurrentPositionTilt::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeCurrentPositionTiltWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WindowCovering::Attributes::CurrentPositionTilt::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNumberOfActuationsLiftWithCompletion:(void (^)(
                                                              NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WindowCovering::Attributes::NumberOfActuationsLift::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeNumberOfActuationsLiftWithParams:(MTRSubscribeParams * _Nonnull)params
                                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WindowCovering::Attributes::NumberOfActuationsLift::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNumberOfActuationsLiftWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                                      completion:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WindowCovering::Attributes::NumberOfActuationsLift::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNumberOfActuationsTiltWithCompletion:(void (^)(
                                                              NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WindowCovering::Attributes::NumberOfActuationsTilt::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeNumberOfActuationsTiltWithParams:(MTRSubscribeParams * _Nonnull)params
                                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WindowCovering::Attributes::NumberOfActuationsTilt::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNumberOfActuationsTiltWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                                      completion:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WindowCovering::Attributes::NumberOfActuationsTilt::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeConfigStatusWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WindowCovering::Attributes::ConfigStatus::TypeInfo;
    return MTRReadAttribute<MTRWindowCoveringConfigStatusAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeConfigStatusWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WindowCovering::Attributes::ConfigStatus::TypeInfo;
    MTRSubscribeAttribute<MTRWindowCoveringConfigStatusAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeConfigStatusWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRWindowCoveringConfigStatusAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(WindowCoveringConfigStatusAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WindowCovering::Attributes::ConfigStatus::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCurrentPositionLiftPercentageWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WindowCovering::Attributes::CurrentPositionLiftPercentage::TypeInfo;
    return MTRReadAttribute<MTRNullableInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeCurrentPositionLiftPercentageWithParams:(MTRSubscribeParams * _Nonnull)params
                                          subscriptionEstablished:
                                              (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                    reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))reportHandler
{
    using TypeInfo = WindowCovering::Attributes::CurrentPositionLiftPercentage::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeCurrentPositionLiftPercentageWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                               endpoint:(NSNumber *)endpoint
                                                                  queue:(dispatch_queue_t)queue
                                                             completion:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WindowCovering::Attributes::CurrentPositionLiftPercentage::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCurrentPositionTiltPercentageWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WindowCovering::Attributes::CurrentPositionTiltPercentage::TypeInfo;
    return MTRReadAttribute<MTRNullableInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeCurrentPositionTiltPercentageWithParams:(MTRSubscribeParams * _Nonnull)params
                                          subscriptionEstablished:
                                              (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                    reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))reportHandler
{
    using TypeInfo = WindowCovering::Attributes::CurrentPositionTiltPercentage::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeCurrentPositionTiltPercentageWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                               endpoint:(NSNumber *)endpoint
                                                                  queue:(dispatch_queue_t)queue
                                                             completion:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WindowCovering::Attributes::CurrentPositionTiltPercentage::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeOperationalStatusWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WindowCovering::Attributes::OperationalStatus::TypeInfo;
    return MTRReadAttribute<MTRWindowCoveringOperationalStatusAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeOperationalStatusWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WindowCovering::Attributes::OperationalStatus::TypeInfo;
    MTRSubscribeAttribute<MTRWindowCoveringOperationalStatusAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeOperationalStatusWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRWindowCoveringOperationalStatusAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(WindowCoveringOperationalStatusAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WindowCovering::Attributes::OperationalStatus::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeTargetPositionLiftPercent100thsWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WindowCovering::Attributes::TargetPositionLiftPercent100ths::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeTargetPositionLiftPercent100thsWithParams:(MTRSubscribeParams * _Nonnull)params
                                            subscriptionEstablished:
                                                (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                      reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))reportHandler
{
    using TypeInfo = WindowCovering::Attributes::TargetPositionLiftPercent100ths::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeTargetPositionLiftPercent100thsWithClusterStateCache:
            (MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                                 endpoint:(NSNumber *)endpoint
                                                                    queue:(dispatch_queue_t)queue
                                                               completion:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WindowCovering::Attributes::TargetPositionLiftPercent100ths::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeTargetPositionTiltPercent100thsWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WindowCovering::Attributes::TargetPositionTiltPercent100ths::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeTargetPositionTiltPercent100thsWithParams:(MTRSubscribeParams * _Nonnull)params
                                            subscriptionEstablished:
                                                (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                      reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))reportHandler
{
    using TypeInfo = WindowCovering::Attributes::TargetPositionTiltPercent100ths::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeTargetPositionTiltPercent100thsWithClusterStateCache:
            (MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                                 endpoint:(NSNumber *)endpoint
                                                                    queue:(dispatch_queue_t)queue
                                                               completion:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WindowCovering::Attributes::TargetPositionTiltPercent100ths::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEndProductTypeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WindowCovering::Attributes::EndProductType::TypeInfo;
    return MTRReadAttribute<MTRWindowCoveringClusterEndProductTypeAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEndProductTypeWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WindowCovering::Attributes::EndProductType::TypeInfo;
    MTRSubscribeAttribute<MTRWindowCoveringClusterEndProductTypeAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeEndProductTypeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRWindowCoveringClusterEndProductTypeAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(WindowCoveringClusterEndProductTypeAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WindowCovering::Attributes::EndProductType::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCurrentPositionLiftPercent100thsWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WindowCovering::Attributes::CurrentPositionLiftPercent100ths::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeCurrentPositionLiftPercent100thsWithParams:(MTRSubscribeParams * _Nonnull)params
                                             subscriptionEstablished:
                                                 (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                       reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))reportHandler
{
    using TypeInfo = WindowCovering::Attributes::CurrentPositionLiftPercent100ths::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeCurrentPositionLiftPercent100thsWithClusterStateCache:
            (MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                                  endpoint:(NSNumber *)endpoint
                                                                     queue:(dispatch_queue_t)queue
                                                                completion:(void (^)(NSNumber * _Nullable value,
                                                                               NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WindowCovering::Attributes::CurrentPositionLiftPercent100ths::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCurrentPositionTiltPercent100thsWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WindowCovering::Attributes::CurrentPositionTiltPercent100ths::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeCurrentPositionTiltPercent100thsWithParams:(MTRSubscribeParams * _Nonnull)params
                                             subscriptionEstablished:
                                                 (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                       reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))reportHandler
{
    using TypeInfo = WindowCovering::Attributes::CurrentPositionTiltPercent100ths::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeCurrentPositionTiltPercent100thsWithClusterStateCache:
            (MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                                  endpoint:(NSNumber *)endpoint
                                                                     queue:(dispatch_queue_t)queue
                                                                completion:(void (^)(NSNumber * _Nullable value,
                                                                               NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WindowCovering::Attributes::CurrentPositionTiltPercent100ths::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeInstalledOpenLimitLiftWithCompletion:(void (^)(
                                                              NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WindowCovering::Attributes::InstalledOpenLimitLift::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeInstalledOpenLimitLiftWithParams:(MTRSubscribeParams * _Nonnull)params
                                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WindowCovering::Attributes::InstalledOpenLimitLift::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeInstalledOpenLimitLiftWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                                      completion:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WindowCovering::Attributes::InstalledOpenLimitLift::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeInstalledClosedLimitLiftWithCompletion:(void (^)(
                                                                NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WindowCovering::Attributes::InstalledClosedLimitLift::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeInstalledClosedLimitLiftWithParams:(MTRSubscribeParams * _Nonnull)params
                                     subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WindowCovering::Attributes::InstalledClosedLimitLift::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeInstalledClosedLimitLiftWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                          endpoint:(NSNumber *)endpoint
                                                             queue:(dispatch_queue_t)queue
                                                        completion:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WindowCovering::Attributes::InstalledClosedLimitLift::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeInstalledOpenLimitTiltWithCompletion:(void (^)(
                                                              NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WindowCovering::Attributes::InstalledOpenLimitTilt::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeInstalledOpenLimitTiltWithParams:(MTRSubscribeParams * _Nonnull)params
                                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WindowCovering::Attributes::InstalledOpenLimitTilt::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeInstalledOpenLimitTiltWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                                      completion:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WindowCovering::Attributes::InstalledOpenLimitTilt::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeInstalledClosedLimitTiltWithCompletion:(void (^)(
                                                                NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WindowCovering::Attributes::InstalledClosedLimitTilt::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeInstalledClosedLimitTiltWithParams:(MTRSubscribeParams * _Nonnull)params
                                     subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WindowCovering::Attributes::InstalledClosedLimitTilt::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeInstalledClosedLimitTiltWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                          endpoint:(NSNumber *)endpoint
                                                             queue:(dispatch_queue_t)queue
                                                        completion:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WindowCovering::Attributes::InstalledClosedLimitTilt::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WindowCovering::Attributes::Mode::TypeInfo;
    return MTRReadAttribute<MTRWindowCoveringModeAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeModeWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeModeWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeModeWithValue:(NSNumber * _Nonnull)value
                             params:(MTRWriteParams * _Nullable)params
                         completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = WindowCovering::Attributes::Mode::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = static_cast<std::remove_reference_t<decltype(cppValue)>>(value.unsignedCharValue);

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeModeWithParams:(MTRSubscribeParams * _Nonnull)params
                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                           reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WindowCovering::Attributes::Mode::TypeInfo;
    MTRSubscribeAttribute<MTRWindowCoveringModeAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                      endpoint:(NSNumber *)endpoint
                                         queue:(dispatch_queue_t)queue
                                    completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRWindowCoveringModeAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(WindowCoveringModeAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WindowCovering::Attributes::Mode::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSafetyStatusWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WindowCovering::Attributes::SafetyStatus::TypeInfo;
    return MTRReadAttribute<MTRWindowCoveringSafetyStatusAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeSafetyStatusWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WindowCovering::Attributes::SafetyStatus::TypeInfo;
    MTRSubscribeAttribute<MTRWindowCoveringSafetyStatusAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeSafetyStatusWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRWindowCoveringSafetyStatusAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(WindowCoveringSafetyStatusAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WindowCovering::Attributes::SafetyStatus::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WindowCovering::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRWindowCoveringGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WindowCovering::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRWindowCoveringGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRWindowCoveringGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(WindowCoveringGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WindowCovering::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WindowCovering::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRWindowCoveringAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WindowCovering::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRWindowCoveringAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRWindowCoveringAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(WindowCoveringAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WindowCovering::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WindowCovering::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRWindowCoveringEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WindowCovering::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRWindowCoveringEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRWindowCoveringEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(WindowCoveringEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WindowCovering::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WindowCovering::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRWindowCoveringAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WindowCovering::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRWindowCoveringAttributeListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRWindowCoveringAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(WindowCoveringAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WindowCovering::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WindowCovering::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WindowCovering::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WindowCovering::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WindowCovering::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WindowCovering::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WindowCovering::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterWindowCovering (Deprecated)

- (void)upOrOpenWithParams:(MTRWindowCoveringClusterUpOrOpenParams * _Nullable)params
         completionHandler:(MTRStatusCompletion)completionHandler
{
    [self upOrOpenWithParams:params completion:completionHandler];
}
- (void)upOrOpenWithCompletionHandler:(MTRStatusCompletion)completionHandler
{
    [self upOrOpenWithParams:nil completionHandler:completionHandler];
}
- (void)downOrCloseWithParams:(MTRWindowCoveringClusterDownOrCloseParams * _Nullable)params
            completionHandler:(MTRStatusCompletion)completionHandler
{
    [self downOrCloseWithParams:params completion:completionHandler];
}
- (void)downOrCloseWithCompletionHandler:(MTRStatusCompletion)completionHandler
{
    [self downOrCloseWithParams:nil completionHandler:completionHandler];
}
- (void)stopMotionWithParams:(MTRWindowCoveringClusterStopMotionParams * _Nullable)params
           completionHandler:(MTRStatusCompletion)completionHandler
{
    [self stopMotionWithParams:params completion:completionHandler];
}
- (void)stopMotionWithCompletionHandler:(MTRStatusCompletion)completionHandler
{
    [self stopMotionWithParams:nil completionHandler:completionHandler];
}
- (void)goToLiftValueWithParams:(MTRWindowCoveringClusterGoToLiftValueParams *)params
              completionHandler:(MTRStatusCompletion)completionHandler
{
    [self goToLiftValueWithParams:params completion:completionHandler];
}
- (void)goToLiftPercentageWithParams:(MTRWindowCoveringClusterGoToLiftPercentageParams *)params
                   completionHandler:(MTRStatusCompletion)completionHandler
{
    [self goToLiftPercentageWithParams:params completion:completionHandler];
}
- (void)goToTiltValueWithParams:(MTRWindowCoveringClusterGoToTiltValueParams *)params
              completionHandler:(MTRStatusCompletion)completionHandler
{
    [self goToTiltValueWithParams:params completion:completionHandler];
}
- (void)goToTiltPercentageWithParams:(MTRWindowCoveringClusterGoToTiltPercentageParams *)params
                   completionHandler:(MTRStatusCompletion)completionHandler
{
    [self goToTiltPercentageWithParams:params completion:completionHandler];
}

- (void)readAttributeTypeWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeTypeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeTypeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                       params:(MTRSubscribeParams * _Nullable)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeTypeWithParams:subscribeParams
                   subscriptionEstablished:subscriptionEstablishedHandler
                             reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                 // Cast is safe because subclass does not add any selectors.
                                 reportHandler(static_cast<NSNumber *>(value), error);
                             }];
}
+ (void)readAttributeTypeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                   endpoint:(NSNumber *)endpoint
                                      queue:(dispatch_queue_t)queue
                          completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeTypeWithClusterStateCache:attributeCacheContainer.realContainer
                                        endpoint:endpoint
                                           queue:queue
                                      completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          completionHandler(static_cast<NSNumber *>(value), error);
                                      }];
}

- (void)readAttributePhysicalClosedLimitLiftWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    [self readAttributePhysicalClosedLimitLiftWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributePhysicalClosedLimitLiftWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                                          params:(MTRSubscribeParams * _Nullable)params
                                         subscriptionEstablished:
                                             (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                   reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePhysicalClosedLimitLiftWithParams:subscribeParams
                                      subscriptionEstablished:subscriptionEstablishedHandler
                                                reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    reportHandler(static_cast<NSNumber *>(value), error);
                                                }];
}
+ (void)readAttributePhysicalClosedLimitLiftWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                             completionHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePhysicalClosedLimitLiftWithClusterStateCache:attributeCacheContainer.realContainer
                                                           endpoint:endpoint
                                                              queue:queue
                                                         completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                             // Cast is safe because subclass does not add any selectors.
                                                             completionHandler(static_cast<NSNumber *>(value), error);
                                                         }];
}

- (void)readAttributePhysicalClosedLimitTiltWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    [self readAttributePhysicalClosedLimitTiltWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributePhysicalClosedLimitTiltWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                                          params:(MTRSubscribeParams * _Nullable)params
                                         subscriptionEstablished:
                                             (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                   reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePhysicalClosedLimitTiltWithParams:subscribeParams
                                      subscriptionEstablished:subscriptionEstablishedHandler
                                                reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    reportHandler(static_cast<NSNumber *>(value), error);
                                                }];
}
+ (void)readAttributePhysicalClosedLimitTiltWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                             completionHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePhysicalClosedLimitTiltWithClusterStateCache:attributeCacheContainer.realContainer
                                                           endpoint:endpoint
                                                              queue:queue
                                                         completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                             // Cast is safe because subclass does not add any selectors.
                                                             completionHandler(static_cast<NSNumber *>(value), error);
                                                         }];
}

- (void)readAttributeCurrentPositionLiftWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentPositionLiftWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeCurrentPositionLiftWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeCurrentPositionLiftWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSNumber *>(value), error);
                                            }];
}
+ (void)readAttributeCurrentPositionLiftWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentPositionLiftWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}

- (void)readAttributeCurrentPositionTiltWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentPositionTiltWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeCurrentPositionTiltWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeCurrentPositionTiltWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSNumber *>(value), error);
                                            }];
}
+ (void)readAttributeCurrentPositionTiltWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentPositionTiltWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}

- (void)readAttributeNumberOfActuationsLiftWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    [self readAttributeNumberOfActuationsLiftWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeNumberOfActuationsLiftWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                                         params:(MTRSubscribeParams * _Nullable)params
                                        subscriptionEstablished:
                                            (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNumberOfActuationsLiftWithParams:subscribeParams
                                     subscriptionEstablished:subscriptionEstablishedHandler
                                               reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   reportHandler(static_cast<NSNumber *>(value), error);
                                               }];
}
+ (void)readAttributeNumberOfActuationsLiftWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                            completionHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNumberOfActuationsLiftWithClusterStateCache:attributeCacheContainer.realContainer
                                                          endpoint:endpoint
                                                             queue:queue
                                                        completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                            // Cast is safe because subclass does not add any selectors.
                                                            completionHandler(static_cast<NSNumber *>(value), error);
                                                        }];
}

- (void)readAttributeNumberOfActuationsTiltWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    [self readAttributeNumberOfActuationsTiltWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeNumberOfActuationsTiltWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                                         params:(MTRSubscribeParams * _Nullable)params
                                        subscriptionEstablished:
                                            (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNumberOfActuationsTiltWithParams:subscribeParams
                                     subscriptionEstablished:subscriptionEstablishedHandler
                                               reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   reportHandler(static_cast<NSNumber *>(value), error);
                                               }];
}
+ (void)readAttributeNumberOfActuationsTiltWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                            completionHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNumberOfActuationsTiltWithClusterStateCache:attributeCacheContainer.realContainer
                                                          endpoint:endpoint
                                                             queue:queue
                                                        completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                            // Cast is safe because subclass does not add any selectors.
                                                            completionHandler(static_cast<NSNumber *>(value), error);
                                                        }];
}

- (void)readAttributeConfigStatusWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeConfigStatusWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeConfigStatusWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeConfigStatusWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributeConfigStatusWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeConfigStatusWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributeCurrentPositionLiftPercentageWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentPositionLiftPercentageWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeCurrentPositionLiftPercentageWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                params:(MTRSubscribeParams * _Nullable)params
                                               subscriptionEstablished:
                                                   (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                         reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeCurrentPositionLiftPercentageWithParams:subscribeParams
                                            subscriptionEstablished:subscriptionEstablishedHandler
                                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          reportHandler(static_cast<NSNumber *>(value), error);
                                                      }];
}
+ (void)readAttributeCurrentPositionLiftPercentageWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                            endpoint:(NSNumber *)endpoint
                                                               queue:(dispatch_queue_t)queue
                                                   completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentPositionLiftPercentageWithClusterStateCache:attributeCacheContainer.realContainer
                                                                 endpoint:endpoint
                                                                    queue:queue
                                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                   // Cast is safe because subclass does not add any selectors.
                                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                                               }];
}

- (void)readAttributeCurrentPositionTiltPercentageWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentPositionTiltPercentageWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeCurrentPositionTiltPercentageWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                params:(MTRSubscribeParams * _Nullable)params
                                               subscriptionEstablished:
                                                   (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                         reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeCurrentPositionTiltPercentageWithParams:subscribeParams
                                            subscriptionEstablished:subscriptionEstablishedHandler
                                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          reportHandler(static_cast<NSNumber *>(value), error);
                                                      }];
}
+ (void)readAttributeCurrentPositionTiltPercentageWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                            endpoint:(NSNumber *)endpoint
                                                               queue:(dispatch_queue_t)queue
                                                   completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentPositionTiltPercentageWithClusterStateCache:attributeCacheContainer.realContainer
                                                                 endpoint:endpoint
                                                                    queue:queue
                                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                   // Cast is safe because subclass does not add any selectors.
                                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                                               }];
}

- (void)readAttributeOperationalStatusWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeOperationalStatusWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeOperationalStatusWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeOperationalStatusWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSNumber *>(value), error);
                                          }];
}
+ (void)readAttributeOperationalStatusWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOperationalStatusWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}

- (void)readAttributeTargetPositionLiftPercent100thsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeTargetPositionLiftPercent100thsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeTargetPositionLiftPercent100thsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                  params:(MTRSubscribeParams * _Nullable)params
                                                 subscriptionEstablished:
                                                     (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                           reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                             NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeTargetPositionLiftPercent100thsWithParams:subscribeParams
                                              subscriptionEstablished:subscriptionEstablishedHandler
                                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                            // Cast is safe because subclass does not add any selectors.
                                                            reportHandler(static_cast<NSNumber *>(value), error);
                                                        }];
}
+ (void)readAttributeTargetPositionLiftPercent100thsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                              endpoint:(NSNumber *)endpoint
                                                                 queue:(dispatch_queue_t)queue
                                                     completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completionHandler
{
    [self
        readAttributeTargetPositionLiftPercent100thsWithClusterStateCache:attributeCacheContainer.realContainer
                                                                 endpoint:endpoint
                                                                    queue:queue
                                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                   // Cast is safe because subclass does not add any selectors.
                                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                                               }];
}

- (void)readAttributeTargetPositionTiltPercent100thsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeTargetPositionTiltPercent100thsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeTargetPositionTiltPercent100thsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                  params:(MTRSubscribeParams * _Nullable)params
                                                 subscriptionEstablished:
                                                     (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                           reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                             NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeTargetPositionTiltPercent100thsWithParams:subscribeParams
                                              subscriptionEstablished:subscriptionEstablishedHandler
                                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                            // Cast is safe because subclass does not add any selectors.
                                                            reportHandler(static_cast<NSNumber *>(value), error);
                                                        }];
}
+ (void)readAttributeTargetPositionTiltPercent100thsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                              endpoint:(NSNumber *)endpoint
                                                                 queue:(dispatch_queue_t)queue
                                                     completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completionHandler
{
    [self
        readAttributeTargetPositionTiltPercent100thsWithClusterStateCache:attributeCacheContainer.realContainer
                                                                 endpoint:endpoint
                                                                    queue:queue
                                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                   // Cast is safe because subclass does not add any selectors.
                                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                                               }];
}

- (void)readAttributeEndProductTypeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeEndProductTypeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeEndProductTypeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeEndProductTypeWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSNumber *>(value), error);
                                       }];
}
+ (void)readAttributeEndProductTypeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeEndProductTypeWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSNumber *>(value), error);
                                                }];
}

- (void)readAttributeCurrentPositionLiftPercent100thsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentPositionLiftPercent100thsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeCurrentPositionLiftPercent100thsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                   params:(MTRSubscribeParams * _Nullable)params
                                                  subscriptionEstablished:
                                                      (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                            reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeCurrentPositionLiftPercent100thsWithParams:subscribeParams
                                               subscriptionEstablished:subscriptionEstablishedHandler
                                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                             // Cast is safe because subclass does not add any selectors.
                                                             reportHandler(static_cast<NSNumber *>(value), error);
                                                         }];
}
+ (void)readAttributeCurrentPositionLiftPercent100thsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                               endpoint:(NSNumber *)endpoint
                                                                  queue:(dispatch_queue_t)queue
                                                      completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentPositionLiftPercent100thsWithClusterStateCache:attributeCacheContainer.realContainer
                                                                    endpoint:endpoint
                                                                       queue:queue
                                                                  completion:^(
                                                                      NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                      // Cast is safe because subclass does not add any selectors.
                                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                                  }];
}

- (void)readAttributeCurrentPositionTiltPercent100thsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentPositionTiltPercent100thsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeCurrentPositionTiltPercent100thsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                   params:(MTRSubscribeParams * _Nullable)params
                                                  subscriptionEstablished:
                                                      (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                            reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeCurrentPositionTiltPercent100thsWithParams:subscribeParams
                                               subscriptionEstablished:subscriptionEstablishedHandler
                                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                             // Cast is safe because subclass does not add any selectors.
                                                             reportHandler(static_cast<NSNumber *>(value), error);
                                                         }];
}
+ (void)readAttributeCurrentPositionTiltPercent100thsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                               endpoint:(NSNumber *)endpoint
                                                                  queue:(dispatch_queue_t)queue
                                                      completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentPositionTiltPercent100thsWithClusterStateCache:attributeCacheContainer.realContainer
                                                                    endpoint:endpoint
                                                                       queue:queue
                                                                  completion:^(
                                                                      NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                      // Cast is safe because subclass does not add any selectors.
                                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                                  }];
}

- (void)readAttributeInstalledOpenLimitLiftWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    [self readAttributeInstalledOpenLimitLiftWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeInstalledOpenLimitLiftWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                                         params:(MTRSubscribeParams * _Nullable)params
                                        subscriptionEstablished:
                                            (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeInstalledOpenLimitLiftWithParams:subscribeParams
                                     subscriptionEstablished:subscriptionEstablishedHandler
                                               reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   reportHandler(static_cast<NSNumber *>(value), error);
                                               }];
}
+ (void)readAttributeInstalledOpenLimitLiftWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                            completionHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInstalledOpenLimitLiftWithClusterStateCache:attributeCacheContainer.realContainer
                                                          endpoint:endpoint
                                                             queue:queue
                                                        completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                            // Cast is safe because subclass does not add any selectors.
                                                            completionHandler(static_cast<NSNumber *>(value), error);
                                                        }];
}

- (void)readAttributeInstalledClosedLimitLiftWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completionHandler
{
    [self readAttributeInstalledClosedLimitLiftWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeInstalledClosedLimitLiftWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                                           params:(MTRSubscribeParams * _Nullable)params
                                          subscriptionEstablished:
                                              (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                    reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeInstalledClosedLimitLiftWithParams:subscribeParams
                                       subscriptionEstablished:subscriptionEstablishedHandler
                                                 reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     reportHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}
+ (void)readAttributeInstalledClosedLimitLiftWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                              completionHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInstalledClosedLimitLiftWithClusterStateCache:attributeCacheContainer.realContainer
                                                            endpoint:endpoint
                                                               queue:queue
                                                          completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                              // Cast is safe because subclass does not add any selectors.
                                                              completionHandler(static_cast<NSNumber *>(value), error);
                                                          }];
}

- (void)readAttributeInstalledOpenLimitTiltWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    [self readAttributeInstalledOpenLimitTiltWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeInstalledOpenLimitTiltWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                                         params:(MTRSubscribeParams * _Nullable)params
                                        subscriptionEstablished:
                                            (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeInstalledOpenLimitTiltWithParams:subscribeParams
                                     subscriptionEstablished:subscriptionEstablishedHandler
                                               reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   reportHandler(static_cast<NSNumber *>(value), error);
                                               }];
}
+ (void)readAttributeInstalledOpenLimitTiltWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                            completionHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInstalledOpenLimitTiltWithClusterStateCache:attributeCacheContainer.realContainer
                                                          endpoint:endpoint
                                                             queue:queue
                                                        completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                            // Cast is safe because subclass does not add any selectors.
                                                            completionHandler(static_cast<NSNumber *>(value), error);
                                                        }];
}

- (void)readAttributeInstalledClosedLimitTiltWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completionHandler
{
    [self readAttributeInstalledClosedLimitTiltWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeInstalledClosedLimitTiltWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                                           params:(MTRSubscribeParams * _Nullable)params
                                          subscriptionEstablished:
                                              (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                    reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeInstalledClosedLimitTiltWithParams:subscribeParams
                                       subscriptionEstablished:subscriptionEstablishedHandler
                                                 reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     reportHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}
+ (void)readAttributeInstalledClosedLimitTiltWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                              completionHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInstalledClosedLimitTiltWithClusterStateCache:attributeCacheContainer.realContainer
                                                            endpoint:endpoint
                                                               queue:queue
                                                          completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                              // Cast is safe because subclass does not add any selectors.
                                                              completionHandler(static_cast<NSNumber *>(value), error);
                                                          }];
}

- (void)readAttributeModeWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeModeWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeModeWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeModeWithValue:(NSNumber * _Nonnull)value
                             params:(MTRWriteParams * _Nullable)params
                  completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeModeWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeModeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                       params:(MTRSubscribeParams * _Nullable)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeModeWithParams:subscribeParams
                   subscriptionEstablished:subscriptionEstablishedHandler
                             reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                 // Cast is safe because subclass does not add any selectors.
                                 reportHandler(static_cast<NSNumber *>(value), error);
                             }];
}
+ (void)readAttributeModeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                   endpoint:(NSNumber *)endpoint
                                      queue:(dispatch_queue_t)queue
                          completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeModeWithClusterStateCache:attributeCacheContainer.realContainer
                                        endpoint:endpoint
                                           queue:queue
                                      completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          completionHandler(static_cast<NSNumber *>(value), error);
                                      }];
}

- (void)readAttributeSafetyStatusWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSafetyStatusWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeSafetyStatusWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeSafetyStatusWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributeSafetyStatusWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSafetyStatusWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterBarrierControl

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)barrierControlGoToPercentWithParams:(MTRBarrierControlClusterBarrierControlGoToPercentParams *)params
                                 completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            BarrierControl::Commands::BarrierControlGoToPercent::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.percentOpen = params.percentOpen.unsignedCharValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)barrierControlStopWithCompletion:(MTRStatusCompletion)completion
{
    [self barrierControlStopWithParams:nil completion:completion];
}
- (void)barrierControlStopWithParams:(MTRBarrierControlClusterBarrierControlStopParams * _Nullable)params
                          completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            BarrierControl::Commands::BarrierControlStop::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeBarrierMovingStateWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BarrierControl::Attributes::BarrierMovingState::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeBarrierMovingStateWithParams:(MTRSubscribeParams * _Nonnull)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BarrierControl::Attributes::BarrierMovingState::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeBarrierMovingStateWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                                  completion:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BarrierControl::Attributes::BarrierMovingState::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBarrierSafetyStatusWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BarrierControl::Attributes::BarrierSafetyStatus::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeBarrierSafetyStatusWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BarrierControl::Attributes::BarrierSafetyStatus::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeBarrierSafetyStatusWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BarrierControl::Attributes::BarrierSafetyStatus::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBarrierCapabilitiesWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BarrierControl::Attributes::BarrierCapabilities::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeBarrierCapabilitiesWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BarrierControl::Attributes::BarrierCapabilities::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeBarrierCapabilitiesWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BarrierControl::Attributes::BarrierCapabilities::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBarrierOpenEventsWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BarrierControl::Attributes::BarrierOpenEvents::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeBarrierOpenEventsWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeBarrierOpenEventsWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeBarrierOpenEventsWithValue:(NSNumber * _Nonnull)value
                                          params:(MTRWriteParams * _Nullable)params
                                      completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BarrierControl::Attributes::BarrierOpenEvents::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeBarrierOpenEventsWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BarrierControl::Attributes::BarrierOpenEvents::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeBarrierOpenEventsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BarrierControl::Attributes::BarrierOpenEvents::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBarrierCloseEventsWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BarrierControl::Attributes::BarrierCloseEvents::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeBarrierCloseEventsWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeBarrierCloseEventsWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeBarrierCloseEventsWithValue:(NSNumber * _Nonnull)value
                                           params:(MTRWriteParams * _Nullable)params
                                       completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BarrierControl::Attributes::BarrierCloseEvents::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeBarrierCloseEventsWithParams:(MTRSubscribeParams * _Nonnull)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BarrierControl::Attributes::BarrierCloseEvents::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeBarrierCloseEventsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                                  completion:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BarrierControl::Attributes::BarrierCloseEvents::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBarrierCommandOpenEventsWithCompletion:(void (^)(
                                                                NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BarrierControl::Attributes::BarrierCommandOpenEvents::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeBarrierCommandOpenEventsWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeBarrierCommandOpenEventsWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeBarrierCommandOpenEventsWithValue:(NSNumber * _Nonnull)value
                                                 params:(MTRWriteParams * _Nullable)params
                                             completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BarrierControl::Attributes::BarrierCommandOpenEvents::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeBarrierCommandOpenEventsWithParams:(MTRSubscribeParams * _Nonnull)params
                                     subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BarrierControl::Attributes::BarrierCommandOpenEvents::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeBarrierCommandOpenEventsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                          endpoint:(NSNumber *)endpoint
                                                             queue:(dispatch_queue_t)queue
                                                        completion:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BarrierControl::Attributes::BarrierCommandOpenEvents::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBarrierCommandCloseEventsWithCompletion:(void (^)(
                                                                 NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BarrierControl::Attributes::BarrierCommandCloseEvents::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeBarrierCommandCloseEventsWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeBarrierCommandCloseEventsWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeBarrierCommandCloseEventsWithValue:(NSNumber * _Nonnull)value
                                                  params:(MTRWriteParams * _Nullable)params
                                              completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BarrierControl::Attributes::BarrierCommandCloseEvents::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeBarrierCommandCloseEventsWithParams:(MTRSubscribeParams * _Nonnull)params
                                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BarrierControl::Attributes::BarrierCommandCloseEvents::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeBarrierCommandCloseEventsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                           endpoint:(NSNumber *)endpoint
                                                              queue:(dispatch_queue_t)queue
                                                         completion:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BarrierControl::Attributes::BarrierCommandCloseEvents::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBarrierOpenPeriodWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BarrierControl::Attributes::BarrierOpenPeriod::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeBarrierOpenPeriodWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeBarrierOpenPeriodWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeBarrierOpenPeriodWithValue:(NSNumber * _Nonnull)value
                                          params:(MTRWriteParams * _Nullable)params
                                      completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BarrierControl::Attributes::BarrierOpenPeriod::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeBarrierOpenPeriodWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BarrierControl::Attributes::BarrierOpenPeriod::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeBarrierOpenPeriodWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BarrierControl::Attributes::BarrierOpenPeriod::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBarrierClosePeriodWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BarrierControl::Attributes::BarrierClosePeriod::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeBarrierClosePeriodWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeBarrierClosePeriodWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeBarrierClosePeriodWithValue:(NSNumber * _Nonnull)value
                                           params:(MTRWriteParams * _Nullable)params
                                       completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BarrierControl::Attributes::BarrierClosePeriod::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeBarrierClosePeriodWithParams:(MTRSubscribeParams * _Nonnull)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BarrierControl::Attributes::BarrierClosePeriod::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeBarrierClosePeriodWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                                  completion:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BarrierControl::Attributes::BarrierClosePeriod::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBarrierPositionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BarrierControl::Attributes::BarrierPosition::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeBarrierPositionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BarrierControl::Attributes::BarrierPosition::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeBarrierPositionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BarrierControl::Attributes::BarrierPosition::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BarrierControl::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRBarrierControlGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BarrierControl::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRBarrierControlGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBarrierControlGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(BarrierControlGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BarrierControl::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BarrierControl::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRBarrierControlAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BarrierControl::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRBarrierControlAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBarrierControlAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(BarrierControlAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BarrierControl::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BarrierControl::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRBarrierControlEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BarrierControl::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRBarrierControlEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBarrierControlEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(BarrierControlEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BarrierControl::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BarrierControl::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRBarrierControlAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BarrierControl::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRBarrierControlAttributeListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBarrierControlAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(BarrierControlAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BarrierControl::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BarrierControl::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BarrierControl::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BarrierControl::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BarrierControl::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BarrierControl::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BarrierControl::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterBarrierControl (Deprecated)

- (void)barrierControlGoToPercentWithParams:(MTRBarrierControlClusterBarrierControlGoToPercentParams *)params
                          completionHandler:(MTRStatusCompletion)completionHandler
{
    [self barrierControlGoToPercentWithParams:params completion:completionHandler];
}
- (void)barrierControlStopWithParams:(MTRBarrierControlClusterBarrierControlStopParams * _Nullable)params
                   completionHandler:(MTRStatusCompletion)completionHandler
{
    [self barrierControlStopWithParams:params completion:completionHandler];
}
- (void)barrierControlStopWithCompletionHandler:(MTRStatusCompletion)completionHandler
{
    [self barrierControlStopWithParams:nil completionHandler:completionHandler];
}

- (void)readAttributeBarrierMovingStateWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    [self readAttributeBarrierMovingStateWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeBarrierMovingStateWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:
                                        (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeBarrierMovingStateWithParams:subscribeParams
                                 subscriptionEstablished:subscriptionEstablishedHandler
                                           reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               reportHandler(static_cast<NSNumber *>(value), error);
                                           }];
}
+ (void)readAttributeBarrierMovingStateWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBarrierMovingStateWithClusterStateCache:attributeCacheContainer.realContainer
                                                      endpoint:endpoint
                                                         queue:queue
                                                    completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                        // Cast is safe because subclass does not add any selectors.
                                                        completionHandler(static_cast<NSNumber *>(value), error);
                                                    }];
}

- (void)readAttributeBarrierSafetyStatusWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeBarrierSafetyStatusWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeBarrierSafetyStatusWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeBarrierSafetyStatusWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSNumber *>(value), error);
                                            }];
}
+ (void)readAttributeBarrierSafetyStatusWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBarrierSafetyStatusWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}

- (void)readAttributeBarrierCapabilitiesWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeBarrierCapabilitiesWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeBarrierCapabilitiesWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeBarrierCapabilitiesWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSNumber *>(value), error);
                                            }];
}
+ (void)readAttributeBarrierCapabilitiesWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBarrierCapabilitiesWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}

- (void)readAttributeBarrierOpenEventsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeBarrierOpenEventsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeBarrierOpenEventsWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeBarrierOpenEventsWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeBarrierOpenEventsWithValue:(NSNumber * _Nonnull)value
                                          params:(MTRWriteParams * _Nullable)params
                               completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeBarrierOpenEventsWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeBarrierOpenEventsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeBarrierOpenEventsWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSNumber *>(value), error);
                                          }];
}
+ (void)readAttributeBarrierOpenEventsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBarrierOpenEventsWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}

- (void)readAttributeBarrierCloseEventsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    [self readAttributeBarrierCloseEventsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeBarrierCloseEventsWithValue:(NSNumber * _Nonnull)value
                                completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeBarrierCloseEventsWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeBarrierCloseEventsWithValue:(NSNumber * _Nonnull)value
                                           params:(MTRWriteParams * _Nullable)params
                                completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeBarrierCloseEventsWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeBarrierCloseEventsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:
                                        (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeBarrierCloseEventsWithParams:subscribeParams
                                 subscriptionEstablished:subscriptionEstablishedHandler
                                           reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               reportHandler(static_cast<NSNumber *>(value), error);
                                           }];
}
+ (void)readAttributeBarrierCloseEventsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBarrierCloseEventsWithClusterStateCache:attributeCacheContainer.realContainer
                                                      endpoint:endpoint
                                                         queue:queue
                                                    completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                        // Cast is safe because subclass does not add any selectors.
                                                        completionHandler(static_cast<NSNumber *>(value), error);
                                                    }];
}

- (void)readAttributeBarrierCommandOpenEventsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completionHandler
{
    [self readAttributeBarrierCommandOpenEventsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeBarrierCommandOpenEventsWithValue:(NSNumber * _Nonnull)value
                                      completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeBarrierCommandOpenEventsWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeBarrierCommandOpenEventsWithValue:(NSNumber * _Nonnull)value
                                                 params:(MTRWriteParams * _Nullable)params
                                      completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeBarrierCommandOpenEventsWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeBarrierCommandOpenEventsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                                           params:(MTRSubscribeParams * _Nullable)params
                                          subscriptionEstablished:
                                              (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                    reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeBarrierCommandOpenEventsWithParams:subscribeParams
                                       subscriptionEstablished:subscriptionEstablishedHandler
                                                 reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     reportHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}
+ (void)readAttributeBarrierCommandOpenEventsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                              completionHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBarrierCommandOpenEventsWithClusterStateCache:attributeCacheContainer.realContainer
                                                            endpoint:endpoint
                                                               queue:queue
                                                          completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                              // Cast is safe because subclass does not add any selectors.
                                                              completionHandler(static_cast<NSNumber *>(value), error);
                                                          }];
}

- (void)readAttributeBarrierCommandCloseEventsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    [self readAttributeBarrierCommandCloseEventsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeBarrierCommandCloseEventsWithValue:(NSNumber * _Nonnull)value
                                       completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeBarrierCommandCloseEventsWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeBarrierCommandCloseEventsWithValue:(NSNumber * _Nonnull)value
                                                  params:(MTRWriteParams * _Nullable)params
                                       completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeBarrierCommandCloseEventsWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeBarrierCommandCloseEventsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                                            params:(MTRSubscribeParams * _Nullable)params
                                           subscriptionEstablished:
                                               (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                     reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeBarrierCommandCloseEventsWithParams:subscribeParams
                                        subscriptionEstablished:subscriptionEstablishedHandler
                                                  reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      reportHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}
+ (void)readAttributeBarrierCommandCloseEventsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                               completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    [self readAttributeBarrierCommandCloseEventsWithClusterStateCache:attributeCacheContainer.realContainer
                                                             endpoint:endpoint
                                                                queue:queue
                                                           completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                               // Cast is safe because subclass does not add any selectors.
                                                               completionHandler(static_cast<NSNumber *>(value), error);
                                                           }];
}

- (void)readAttributeBarrierOpenPeriodWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeBarrierOpenPeriodWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeBarrierOpenPeriodWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeBarrierOpenPeriodWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeBarrierOpenPeriodWithValue:(NSNumber * _Nonnull)value
                                          params:(MTRWriteParams * _Nullable)params
                               completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeBarrierOpenPeriodWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeBarrierOpenPeriodWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeBarrierOpenPeriodWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSNumber *>(value), error);
                                          }];
}
+ (void)readAttributeBarrierOpenPeriodWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBarrierOpenPeriodWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}

- (void)readAttributeBarrierClosePeriodWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    [self readAttributeBarrierClosePeriodWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeBarrierClosePeriodWithValue:(NSNumber * _Nonnull)value
                                completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeBarrierClosePeriodWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeBarrierClosePeriodWithValue:(NSNumber * _Nonnull)value
                                           params:(MTRWriteParams * _Nullable)params
                                completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeBarrierClosePeriodWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeBarrierClosePeriodWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:
                                        (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeBarrierClosePeriodWithParams:subscribeParams
                                 subscriptionEstablished:subscriptionEstablishedHandler
                                           reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               reportHandler(static_cast<NSNumber *>(value), error);
                                           }];
}
+ (void)readAttributeBarrierClosePeriodWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBarrierClosePeriodWithClusterStateCache:attributeCacheContainer.realContainer
                                                      endpoint:endpoint
                                                         queue:queue
                                                    completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                        // Cast is safe because subclass does not add any selectors.
                                                        completionHandler(static_cast<NSNumber *>(value), error);
                                                    }];
}

- (void)readAttributeBarrierPositionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeBarrierPositionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeBarrierPositionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeBarrierPositionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeBarrierPositionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBarrierPositionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterPumpConfigurationAndControl

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)readAttributeMaxPressureWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PumpConfigurationAndControl::Attributes::MaxPressure::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMaxPressureWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PumpConfigurationAndControl::Attributes::MaxPressure::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMaxPressureWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PumpConfigurationAndControl::Attributes::MaxPressure::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMaxSpeedWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PumpConfigurationAndControl::Attributes::MaxSpeed::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMaxSpeedWithParams:(MTRSubscribeParams * _Nonnull)params
                     subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                               reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PumpConfigurationAndControl::Attributes::MaxSpeed::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMaxSpeedWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                        completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PumpConfigurationAndControl::Attributes::MaxSpeed::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMaxFlowWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PumpConfigurationAndControl::Attributes::MaxFlow::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMaxFlowWithParams:(MTRSubscribeParams * _Nonnull)params
                    subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                              reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PumpConfigurationAndControl::Attributes::MaxFlow::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMaxFlowWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                       completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PumpConfigurationAndControl::Attributes::MaxFlow::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMinConstPressureWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PumpConfigurationAndControl::Attributes::MinConstPressure::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMinConstPressureWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PumpConfigurationAndControl::Attributes::MinConstPressure::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMinConstPressureWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PumpConfigurationAndControl::Attributes::MinConstPressure::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMaxConstPressureWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PumpConfigurationAndControl::Attributes::MaxConstPressure::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMaxConstPressureWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PumpConfigurationAndControl::Attributes::MaxConstPressure::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMaxConstPressureWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PumpConfigurationAndControl::Attributes::MaxConstPressure::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMinCompPressureWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PumpConfigurationAndControl::Attributes::MinCompPressure::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMinCompPressureWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PumpConfigurationAndControl::Attributes::MinCompPressure::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMinCompPressureWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PumpConfigurationAndControl::Attributes::MinCompPressure::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMaxCompPressureWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PumpConfigurationAndControl::Attributes::MaxCompPressure::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMaxCompPressureWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PumpConfigurationAndControl::Attributes::MaxCompPressure::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMaxCompPressureWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PumpConfigurationAndControl::Attributes::MaxCompPressure::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMinConstSpeedWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PumpConfigurationAndControl::Attributes::MinConstSpeed::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMinConstSpeedWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PumpConfigurationAndControl::Attributes::MinConstSpeed::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMinConstSpeedWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PumpConfigurationAndControl::Attributes::MinConstSpeed::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMaxConstSpeedWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PumpConfigurationAndControl::Attributes::MaxConstSpeed::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMaxConstSpeedWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PumpConfigurationAndControl::Attributes::MaxConstSpeed::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMaxConstSpeedWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PumpConfigurationAndControl::Attributes::MaxConstSpeed::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMinConstFlowWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PumpConfigurationAndControl::Attributes::MinConstFlow::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMinConstFlowWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PumpConfigurationAndControl::Attributes::MinConstFlow::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMinConstFlowWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PumpConfigurationAndControl::Attributes::MinConstFlow::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMaxConstFlowWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PumpConfigurationAndControl::Attributes::MaxConstFlow::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMaxConstFlowWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PumpConfigurationAndControl::Attributes::MaxConstFlow::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMaxConstFlowWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PumpConfigurationAndControl::Attributes::MaxConstFlow::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMinConstTempWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PumpConfigurationAndControl::Attributes::MinConstTemp::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMinConstTempWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PumpConfigurationAndControl::Attributes::MinConstTemp::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMinConstTempWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PumpConfigurationAndControl::Attributes::MinConstTemp::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMaxConstTempWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PumpConfigurationAndControl::Attributes::MaxConstTemp::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMaxConstTempWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PumpConfigurationAndControl::Attributes::MaxConstTemp::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMaxConstTempWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PumpConfigurationAndControl::Attributes::MaxConstTemp::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePumpStatusWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PumpConfigurationAndControl::Attributes::PumpStatus::TypeInfo;
    return MTRReadAttribute<MTRPumpConfigurationAndControlPumpStatusAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePumpStatusWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PumpConfigurationAndControl::Attributes::PumpStatus::TypeInfo;
    MTRSubscribeAttribute<MTRPumpConfigurationAndControlPumpStatusAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributePumpStatusWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRPumpConfigurationAndControlPumpStatusAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(PumpConfigurationAndControlPumpStatusAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PumpConfigurationAndControl::Attributes::PumpStatus::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEffectiveOperationModeWithCompletion:(void (^)(
                                                              NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PumpConfigurationAndControl::Attributes::EffectiveOperationMode::TypeInfo;
    return MTRReadAttribute<MTRPumpConfigurationAndControlClusterOperationModeEnumAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEffectiveOperationModeWithParams:(MTRSubscribeParams * _Nonnull)params
                                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PumpConfigurationAndControl::Attributes::EffectiveOperationMode::TypeInfo;
    MTRSubscribeAttribute<MTRPumpConfigurationAndControlClusterOperationModeEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeEffectiveOperationModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                                      completion:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completion
{
    auto * bridge = new MTRPumpConfigurationAndControlClusterOperationModeEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(PumpConfigurationAndControlClusterOperationModeEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PumpConfigurationAndControl::Attributes::EffectiveOperationMode::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEffectiveControlModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PumpConfigurationAndControl::Attributes::EffectiveControlMode::TypeInfo;
    return MTRReadAttribute<MTRPumpConfigurationAndControlClusterControlModeEnumAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEffectiveControlModeWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PumpConfigurationAndControl::Attributes::EffectiveControlMode::TypeInfo;
    MTRSubscribeAttribute<MTRPumpConfigurationAndControlClusterControlModeEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeEffectiveControlModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRPumpConfigurationAndControlClusterControlModeEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(PumpConfigurationAndControlClusterControlModeEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PumpConfigurationAndControl::Attributes::EffectiveControlMode::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCapacityWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PumpConfigurationAndControl::Attributes::Capacity::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeCapacityWithParams:(MTRSubscribeParams * _Nonnull)params
                     subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                               reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PumpConfigurationAndControl::Attributes::Capacity::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeCapacityWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                        completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PumpConfigurationAndControl::Attributes::Capacity::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSpeedWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PumpConfigurationAndControl::Attributes::Speed::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeSpeedWithParams:(MTRSubscribeParams * _Nonnull)params
                  subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                            reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PumpConfigurationAndControl::Attributes::Speed::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeSpeedWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                                     completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PumpConfigurationAndControl::Attributes::Speed::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeLifetimeRunningHoursWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PumpConfigurationAndControl::Attributes::LifetimeRunningHours::TypeInfo;
    return MTRReadAttribute<MTRNullableInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeLifetimeRunningHoursWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeLifetimeRunningHoursWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeLifetimeRunningHoursWithValue:(NSNumber * _Nullable)value
                                             params:(MTRWriteParams * _Nullable)params
                                         completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = PumpConfigurationAndControl::Attributes::LifetimeRunningHours::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedIntValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeLifetimeRunningHoursWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PumpConfigurationAndControl::Attributes::LifetimeRunningHours::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeLifetimeRunningHoursWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PumpConfigurationAndControl::Attributes::LifetimeRunningHours::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePowerWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PumpConfigurationAndControl::Attributes::Power::TypeInfo;
    return MTRReadAttribute<MTRNullableInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePowerWithParams:(MTRSubscribeParams * _Nonnull)params
                  subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                            reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PumpConfigurationAndControl::Attributes::Power::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePowerWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                                     completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PumpConfigurationAndControl::Attributes::Power::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeLifetimeEnergyConsumedWithCompletion:(void (^)(
                                                              NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PumpConfigurationAndControl::Attributes::LifetimeEnergyConsumed::TypeInfo;
    return MTRReadAttribute<MTRNullableInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeLifetimeEnergyConsumedWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeLifetimeEnergyConsumedWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeLifetimeEnergyConsumedWithValue:(NSNumber * _Nullable)value
                                               params:(MTRWriteParams * _Nullable)params
                                           completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = PumpConfigurationAndControl::Attributes::LifetimeEnergyConsumed::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedIntValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeLifetimeEnergyConsumedWithParams:(MTRSubscribeParams * _Nonnull)params
                                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PumpConfigurationAndControl::Attributes::LifetimeEnergyConsumed::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeLifetimeEnergyConsumedWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                                      completion:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PumpConfigurationAndControl::Attributes::LifetimeEnergyConsumed::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeOperationModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PumpConfigurationAndControl::Attributes::OperationMode::TypeInfo;
    return MTRReadAttribute<MTRPumpConfigurationAndControlClusterOperationModeEnumAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeOperationModeWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeOperationModeWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeOperationModeWithValue:(NSNumber * _Nonnull)value
                                      params:(MTRWriteParams * _Nullable)params
                                  completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = PumpConfigurationAndControl::Attributes::OperationMode::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = static_cast<std::remove_reference_t<decltype(cppValue)>>(value.unsignedCharValue);

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeOperationModeWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PumpConfigurationAndControl::Attributes::OperationMode::TypeInfo;
    MTRSubscribeAttribute<MTRPumpConfigurationAndControlClusterOperationModeEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeOperationModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRPumpConfigurationAndControlClusterOperationModeEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(PumpConfigurationAndControlClusterOperationModeEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PumpConfigurationAndControl::Attributes::OperationMode::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeControlModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PumpConfigurationAndControl::Attributes::ControlMode::TypeInfo;
    return MTRReadAttribute<MTRPumpConfigurationAndControlClusterControlModeEnumAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeControlModeWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeControlModeWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeControlModeWithValue:(NSNumber * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                                completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = PumpConfigurationAndControl::Attributes::ControlMode::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = static_cast<std::remove_reference_t<decltype(cppValue)>>(value.unsignedCharValue);

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeControlModeWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PumpConfigurationAndControl::Attributes::ControlMode::TypeInfo;
    MTRSubscribeAttribute<MTRPumpConfigurationAndControlClusterControlModeEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeControlModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRPumpConfigurationAndControlClusterControlModeEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(PumpConfigurationAndControlClusterControlModeEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PumpConfigurationAndControl::Attributes::ControlMode::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PumpConfigurationAndControl::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRPumpConfigurationAndControlGeneratedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PumpConfigurationAndControl::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRPumpConfigurationAndControlGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRPumpConfigurationAndControlGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(PumpConfigurationAndControlGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PumpConfigurationAndControl::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PumpConfigurationAndControl::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRPumpConfigurationAndControlAcceptedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PumpConfigurationAndControl::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRPumpConfigurationAndControlAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRPumpConfigurationAndControlAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(PumpConfigurationAndControlAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PumpConfigurationAndControl::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PumpConfigurationAndControl::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRPumpConfigurationAndControlEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PumpConfigurationAndControl::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRPumpConfigurationAndControlEventListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRPumpConfigurationAndControlEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(PumpConfigurationAndControlEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PumpConfigurationAndControl::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PumpConfigurationAndControl::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRPumpConfigurationAndControlAttributeListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PumpConfigurationAndControl::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRPumpConfigurationAndControlAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRPumpConfigurationAndControlAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(PumpConfigurationAndControlAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PumpConfigurationAndControl::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PumpConfigurationAndControl::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PumpConfigurationAndControl::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PumpConfigurationAndControl::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PumpConfigurationAndControl::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PumpConfigurationAndControl::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PumpConfigurationAndControl::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterPumpConfigurationAndControl (Deprecated)

- (void)readAttributeMaxPressureWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxPressureWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeMaxPressureWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMaxPressureWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSNumber *>(value), error);
                                    }];
}
+ (void)readAttributeMaxPressureWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxPressureWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                             }];
}

- (void)readAttributeMaxSpeedWithCompletionHandler:(void (^)(
                                                       NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxSpeedWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeMaxSpeedWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMaxSpeedWithParams:subscribeParams
                       subscriptionEstablished:subscriptionEstablishedHandler
                                 reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                     // Cast is safe because subclass does not add any selectors.
                                     reportHandler(static_cast<NSNumber *>(value), error);
                                 }];
}
+ (void)readAttributeMaxSpeedWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxSpeedWithClusterStateCache:attributeCacheContainer.realContainer
                                            endpoint:endpoint
                                               queue:queue
                                          completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              completionHandler(static_cast<NSNumber *>(value), error);
                                          }];
}

- (void)readAttributeMaxFlowWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxFlowWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeMaxFlowWithMinInterval:(NSNumber * _Nonnull)minInterval
                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                          params:(MTRSubscribeParams * _Nullable)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMaxFlowWithParams:subscribeParams
                      subscriptionEstablished:subscriptionEstablishedHandler
                                reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                    // Cast is safe because subclass does not add any selectors.
                                    reportHandler(static_cast<NSNumber *>(value), error);
                                }];
}
+ (void)readAttributeMaxFlowWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                      endpoint:(NSNumber *)endpoint
                                         queue:(dispatch_queue_t)queue
                             completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxFlowWithClusterStateCache:attributeCacheContainer.realContainer
                                           endpoint:endpoint
                                              queue:queue
                                         completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             completionHandler(static_cast<NSNumber *>(value), error);
                                         }];
}

- (void)readAttributeMinConstPressureWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeMinConstPressureWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)
    subscribeAttributeMinConstPressureWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMinConstPressureWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributeMinConstPressureWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMinConstPressureWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeMaxConstPressureWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxConstPressureWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)
    subscribeAttributeMaxConstPressureWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMaxConstPressureWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributeMaxConstPressureWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxConstPressureWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeMinCompPressureWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeMinCompPressureWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeMinCompPressureWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMinCompPressureWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeMinCompPressureWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMinCompPressureWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (void)readAttributeMaxCompPressureWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxCompPressureWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeMaxCompPressureWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMaxCompPressureWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeMaxCompPressureWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxCompPressureWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (void)readAttributeMinConstSpeedWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMinConstSpeedWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeMinConstSpeedWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMinConstSpeedWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributeMinConstSpeedWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMinConstSpeedWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributeMaxConstSpeedWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxConstSpeedWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeMaxConstSpeedWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMaxConstSpeedWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributeMaxConstSpeedWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxConstSpeedWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributeMinConstFlowWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMinConstFlowWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeMinConstFlowWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMinConstFlowWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributeMinConstFlowWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMinConstFlowWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributeMaxConstFlowWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxConstFlowWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeMaxConstFlowWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMaxConstFlowWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributeMaxConstFlowWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxConstFlowWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributeMinConstTempWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMinConstTempWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeMinConstTempWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMinConstTempWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributeMinConstTempWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMinConstTempWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributeMaxConstTempWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxConstTempWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeMaxConstTempWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMaxConstTempWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributeMaxConstTempWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxConstTempWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributePumpStatusWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePumpStatusWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributePumpStatusWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePumpStatusWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributePumpStatusWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePumpStatusWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeEffectiveOperationModeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    [self readAttributeEffectiveOperationModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeEffectiveOperationModeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                                         params:(MTRSubscribeParams * _Nullable)params
                                        subscriptionEstablished:
                                            (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeEffectiveOperationModeWithParams:subscribeParams
                                     subscriptionEstablished:subscriptionEstablishedHandler
                                               reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   reportHandler(static_cast<NSNumber *>(value), error);
                                               }];
}
+ (void)readAttributeEffectiveOperationModeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                            completionHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeEffectiveOperationModeWithClusterStateCache:attributeCacheContainer.realContainer
                                                          endpoint:endpoint
                                                             queue:queue
                                                        completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                            // Cast is safe because subclass does not add any selectors.
                                                            completionHandler(static_cast<NSNumber *>(value), error);
                                                        }];
}

- (void)readAttributeEffectiveControlModeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeEffectiveControlModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeEffectiveControlModeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeEffectiveControlModeWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSNumber *>(value), error);
                                             }];
}
+ (void)readAttributeEffectiveControlModeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeEffectiveControlModeWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSNumber *>(value), error);
                                                      }];
}

- (void)readAttributeCapacityWithCompletionHandler:(void (^)(
                                                       NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCapacityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeCapacityWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeCapacityWithParams:subscribeParams
                       subscriptionEstablished:subscriptionEstablishedHandler
                                 reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                     // Cast is safe because subclass does not add any selectors.
                                     reportHandler(static_cast<NSNumber *>(value), error);
                                 }];
}
+ (void)readAttributeCapacityWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCapacityWithClusterStateCache:attributeCacheContainer.realContainer
                                            endpoint:endpoint
                                               queue:queue
                                          completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              completionHandler(static_cast<NSNumber *>(value), error);
                                          }];
}

- (void)readAttributeSpeedWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSpeedWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeSpeedWithMinInterval:(NSNumber * _Nonnull)minInterval
                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                        params:(MTRSubscribeParams * _Nullable)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeSpeedWithParams:subscribeParams
                    subscriptionEstablished:subscriptionEstablishedHandler
                              reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                  // Cast is safe because subclass does not add any selectors.
                                  reportHandler(static_cast<NSNumber *>(value), error);
                              }];
}
+ (void)readAttributeSpeedWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                    endpoint:(NSNumber *)endpoint
                                       queue:(dispatch_queue_t)queue
                           completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSpeedWithClusterStateCache:attributeCacheContainer.realContainer
                                         endpoint:endpoint
                                            queue:queue
                                       completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           completionHandler(static_cast<NSNumber *>(value), error);
                                       }];
}

- (void)readAttributeLifetimeRunningHoursWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeLifetimeRunningHoursWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeLifetimeRunningHoursWithValue:(NSNumber * _Nullable)value
                                  completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeLifetimeRunningHoursWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeLifetimeRunningHoursWithValue:(NSNumber * _Nullable)value
                                             params:(MTRWriteParams * _Nullable)params
                                  completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeLifetimeRunningHoursWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeLifetimeRunningHoursWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeLifetimeRunningHoursWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSNumber *>(value), error);
                                             }];
}
+ (void)readAttributeLifetimeRunningHoursWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLifetimeRunningHoursWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSNumber *>(value), error);
                                                      }];
}

- (void)readAttributePowerWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePowerWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributePowerWithMinInterval:(NSNumber * _Nonnull)minInterval
                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                        params:(MTRSubscribeParams * _Nullable)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePowerWithParams:subscribeParams
                    subscriptionEstablished:subscriptionEstablishedHandler
                              reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                  // Cast is safe because subclass does not add any selectors.
                                  reportHandler(static_cast<NSNumber *>(value), error);
                              }];
}
+ (void)readAttributePowerWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                    endpoint:(NSNumber *)endpoint
                                       queue:(dispatch_queue_t)queue
                           completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePowerWithClusterStateCache:attributeCacheContainer.realContainer
                                         endpoint:endpoint
                                            queue:queue
                                       completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           completionHandler(static_cast<NSNumber *>(value), error);
                                       }];
}

- (void)readAttributeLifetimeEnergyConsumedWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    [self readAttributeLifetimeEnergyConsumedWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeLifetimeEnergyConsumedWithValue:(NSNumber * _Nullable)value
                                    completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeLifetimeEnergyConsumedWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeLifetimeEnergyConsumedWithValue:(NSNumber * _Nullable)value
                                               params:(MTRWriteParams * _Nullable)params
                                    completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeLifetimeEnergyConsumedWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeLifetimeEnergyConsumedWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                                         params:(MTRSubscribeParams * _Nullable)params
                                        subscriptionEstablished:
                                            (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeLifetimeEnergyConsumedWithParams:subscribeParams
                                     subscriptionEstablished:subscriptionEstablishedHandler
                                               reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   reportHandler(static_cast<NSNumber *>(value), error);
                                               }];
}
+ (void)readAttributeLifetimeEnergyConsumedWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                            completionHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLifetimeEnergyConsumedWithClusterStateCache:attributeCacheContainer.realContainer
                                                          endpoint:endpoint
                                                             queue:queue
                                                        completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                            // Cast is safe because subclass does not add any selectors.
                                                            completionHandler(static_cast<NSNumber *>(value), error);
                                                        }];
}

- (void)readAttributeOperationModeWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOperationModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeOperationModeWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeOperationModeWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeOperationModeWithValue:(NSNumber * _Nonnull)value
                                      params:(MTRWriteParams * _Nullable)params
                           completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeOperationModeWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeOperationModeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeOperationModeWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributeOperationModeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOperationModeWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributeControlModeWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeControlModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeControlModeWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeControlModeWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeControlModeWithValue:(NSNumber * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                         completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeControlModeWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeControlModeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeControlModeWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSNumber *>(value), error);
                                    }];
}
+ (void)readAttributeControlModeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeControlModeWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                             }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterThermostat

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)setpointRaiseLowerWithParams:(MTRThermostatClusterSetpointRaiseLowerParams *)params
                          completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            Thermostat::Commands::SetpointRaiseLower::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.mode = static_cast<std::remove_reference_t<decltype(request.mode)>>(params.mode.unsignedCharValue);
            request.amount = params.amount.charValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)setWeeklyScheduleWithParams:(MTRThermostatClusterSetWeeklyScheduleParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            Thermostat::Commands::SetWeeklySchedule::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.numberOfTransitionsForSequence = params.numberOfTransitionsForSequence.unsignedCharValue;
            request.dayOfWeekForSequence = static_cast<std::remove_reference_t<decltype(request.dayOfWeekForSequence)>>(
                params.dayOfWeekForSequence.unsignedCharValue);
            request.modeForSequence
                = static_cast<std::remove_reference_t<decltype(request.modeForSequence)>>(params.modeForSequence.unsignedCharValue);
            {
                using ListType_0 = std::remove_reference_t<decltype(request.transitions)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (params.transitions.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(params.transitions.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < params.transitions.count; ++i_0) {
                        if (![params.transitions[i_0] isKindOfClass:[MTRThermostatClusterThermostatScheduleTransition class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (MTRThermostatClusterThermostatScheduleTransition *) params.transitions[i_0];
                        listHolder_0->mList[i_0].transitionTime = element_0.transitionTime.unsignedShortValue;
                        if (element_0.heatSetpoint == nil) {
                            listHolder_0->mList[i_0].heatSetpoint.SetNull();
                        } else {
                            auto & nonNullValue_2 = listHolder_0->mList[i_0].heatSetpoint.SetNonNull();
                            nonNullValue_2 = element_0.heatSetpoint.shortValue;
                        }
                        if (element_0.coolSetpoint == nil) {
                            listHolder_0->mList[i_0].coolSetpoint.SetNull();
                        } else {
                            auto & nonNullValue_2 = listHolder_0->mList[i_0].coolSetpoint.SetNonNull();
                            nonNullValue_2 = element_0.coolSetpoint.shortValue;
                        }
                    }
                    request.transitions = ListType_0(listHolder_0->mList, params.transitions.count);
                } else {
                    request.transitions = ListType_0();
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)getWeeklyScheduleWithParams:(MTRThermostatClusterGetWeeklyScheduleParams *)params
                         completion:(void (^)(MTRThermostatClusterGetWeeklyScheduleResponseParams * _Nullable data,
                                        NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRThermostatClusterGetWeeklyScheduleResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            ThermostatClusterGetWeeklyScheduleResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRThermostatClusterGetWeeklyScheduleResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            Thermostat::Commands::GetWeeklySchedule::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.daysToReturn
                = static_cast<std::remove_reference_t<decltype(request.daysToReturn)>>(params.daysToReturn.unsignedCharValue);
            request.modeToReturn
                = static_cast<std::remove_reference_t<decltype(request.modeToReturn)>>(params.modeToReturn.unsignedCharValue);

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)clearWeeklyScheduleWithCompletion:(MTRStatusCompletion)completion
{
    [self clearWeeklyScheduleWithParams:nil completion:completion];
}
- (void)clearWeeklyScheduleWithParams:(MTRThermostatClusterClearWeeklyScheduleParams * _Nullable)params
                           completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            Thermostat::Commands::ClearWeeklySchedule::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeLocalTemperatureWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::LocalTemperature::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeLocalTemperatureWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::LocalTemperature::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeLocalTemperatureWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::LocalTemperature::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeOutdoorTemperatureWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::OutdoorTemperature::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeOutdoorTemperatureWithParams:(MTRSubscribeParams * _Nonnull)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::OutdoorTemperature::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeOutdoorTemperatureWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                                  completion:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::OutdoorTemperature::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeOccupancyWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::Occupancy::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeOccupancyWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::Occupancy::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeOccupancyWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::Occupancy::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAbsMinHeatSetpointLimitWithCompletion:(void (^)(
                                                               NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::AbsMinHeatSetpointLimit::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAbsMinHeatSetpointLimitWithParams:(MTRSubscribeParams * _Nonnull)params
                                    subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::AbsMinHeatSetpointLimit::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAbsMinHeatSetpointLimitWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                         endpoint:(NSNumber *)endpoint
                                                            queue:(dispatch_queue_t)queue
                                                       completion:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::AbsMinHeatSetpointLimit::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAbsMaxHeatSetpointLimitWithCompletion:(void (^)(
                                                               NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::AbsMaxHeatSetpointLimit::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAbsMaxHeatSetpointLimitWithParams:(MTRSubscribeParams * _Nonnull)params
                                    subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::AbsMaxHeatSetpointLimit::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAbsMaxHeatSetpointLimitWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                         endpoint:(NSNumber *)endpoint
                                                            queue:(dispatch_queue_t)queue
                                                       completion:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::AbsMaxHeatSetpointLimit::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAbsMinCoolSetpointLimitWithCompletion:(void (^)(
                                                               NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::AbsMinCoolSetpointLimit::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAbsMinCoolSetpointLimitWithParams:(MTRSubscribeParams * _Nonnull)params
                                    subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::AbsMinCoolSetpointLimit::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAbsMinCoolSetpointLimitWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                         endpoint:(NSNumber *)endpoint
                                                            queue:(dispatch_queue_t)queue
                                                       completion:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::AbsMinCoolSetpointLimit::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAbsMaxCoolSetpointLimitWithCompletion:(void (^)(
                                                               NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::AbsMaxCoolSetpointLimit::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAbsMaxCoolSetpointLimitWithParams:(MTRSubscribeParams * _Nonnull)params
                                    subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::AbsMaxCoolSetpointLimit::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAbsMaxCoolSetpointLimitWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                         endpoint:(NSNumber *)endpoint
                                                            queue:(dispatch_queue_t)queue
                                                       completion:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::AbsMaxCoolSetpointLimit::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePICoolingDemandWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::PICoolingDemand::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePICoolingDemandWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::PICoolingDemand::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePICoolingDemandWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::PICoolingDemand::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePIHeatingDemandWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::PIHeatingDemand::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePIHeatingDemandWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::PIHeatingDemand::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePIHeatingDemandWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::PIHeatingDemand::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeHVACSystemTypeConfigurationWithCompletion:(void (^)(
                                                                   NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::HVACSystemTypeConfiguration::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeHVACSystemTypeConfigurationWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeHVACSystemTypeConfigurationWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeHVACSystemTypeConfigurationWithValue:(NSNumber * _Nonnull)value
                                                    params:(MTRWriteParams * _Nullable)params
                                                completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::HVACSystemTypeConfiguration::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeHVACSystemTypeConfigurationWithParams:(MTRSubscribeParams * _Nonnull)params
                                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::HVACSystemTypeConfiguration::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeHVACSystemTypeConfigurationWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                             endpoint:(NSNumber *)endpoint
                                                                queue:(dispatch_queue_t)queue
                                                           completion:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::HVACSystemTypeConfiguration::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeLocalTemperatureCalibrationWithCompletion:(void (^)(
                                                                   NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::LocalTemperatureCalibration::TypeInfo;
    return MTRReadAttribute<MTRInt8sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeLocalTemperatureCalibrationWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeLocalTemperatureCalibrationWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeLocalTemperatureCalibrationWithValue:(NSNumber * _Nonnull)value
                                                    params:(MTRWriteParams * _Nullable)params
                                                completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::LocalTemperatureCalibration::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.charValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeLocalTemperatureCalibrationWithParams:(MTRSubscribeParams * _Nonnull)params
                                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::LocalTemperatureCalibration::TypeInfo;
    MTRSubscribeAttribute<MTRInt8sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeLocalTemperatureCalibrationWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                             endpoint:(NSNumber *)endpoint
                                                                queue:(dispatch_queue_t)queue
                                                           completion:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::LocalTemperatureCalibration::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeOccupiedCoolingSetpointWithCompletion:(void (^)(
                                                               NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::OccupiedCoolingSetpoint::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeOccupiedCoolingSetpointWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeOccupiedCoolingSetpointWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeOccupiedCoolingSetpointWithValue:(NSNumber * _Nonnull)value
                                                params:(MTRWriteParams * _Nullable)params
                                            completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::OccupiedCoolingSetpoint::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.shortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeOccupiedCoolingSetpointWithParams:(MTRSubscribeParams * _Nonnull)params
                                    subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::OccupiedCoolingSetpoint::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeOccupiedCoolingSetpointWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                         endpoint:(NSNumber *)endpoint
                                                            queue:(dispatch_queue_t)queue
                                                       completion:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::OccupiedCoolingSetpoint::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeOccupiedHeatingSetpointWithCompletion:(void (^)(
                                                               NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::OccupiedHeatingSetpoint::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeOccupiedHeatingSetpointWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeOccupiedHeatingSetpointWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeOccupiedHeatingSetpointWithValue:(NSNumber * _Nonnull)value
                                                params:(MTRWriteParams * _Nullable)params
                                            completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::OccupiedHeatingSetpoint::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.shortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeOccupiedHeatingSetpointWithParams:(MTRSubscribeParams * _Nonnull)params
                                    subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::OccupiedHeatingSetpoint::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeOccupiedHeatingSetpointWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                         endpoint:(NSNumber *)endpoint
                                                            queue:(dispatch_queue_t)queue
                                                       completion:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::OccupiedHeatingSetpoint::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeUnoccupiedCoolingSetpointWithCompletion:(void (^)(
                                                                 NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::UnoccupiedCoolingSetpoint::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeUnoccupiedCoolingSetpointWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeUnoccupiedCoolingSetpointWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeUnoccupiedCoolingSetpointWithValue:(NSNumber * _Nonnull)value
                                                  params:(MTRWriteParams * _Nullable)params
                                              completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::UnoccupiedCoolingSetpoint::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.shortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeUnoccupiedCoolingSetpointWithParams:(MTRSubscribeParams * _Nonnull)params
                                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::UnoccupiedCoolingSetpoint::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeUnoccupiedCoolingSetpointWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                           endpoint:(NSNumber *)endpoint
                                                              queue:(dispatch_queue_t)queue
                                                         completion:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::UnoccupiedCoolingSetpoint::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeUnoccupiedHeatingSetpointWithCompletion:(void (^)(
                                                                 NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::UnoccupiedHeatingSetpoint::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeUnoccupiedHeatingSetpointWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeUnoccupiedHeatingSetpointWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeUnoccupiedHeatingSetpointWithValue:(NSNumber * _Nonnull)value
                                                  params:(MTRWriteParams * _Nullable)params
                                              completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::UnoccupiedHeatingSetpoint::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.shortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeUnoccupiedHeatingSetpointWithParams:(MTRSubscribeParams * _Nonnull)params
                                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::UnoccupiedHeatingSetpoint::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeUnoccupiedHeatingSetpointWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                           endpoint:(NSNumber *)endpoint
                                                              queue:(dispatch_queue_t)queue
                                                         completion:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::UnoccupiedHeatingSetpoint::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMinHeatSetpointLimitWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::MinHeatSetpointLimit::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeMinHeatSetpointLimitWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeMinHeatSetpointLimitWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeMinHeatSetpointLimitWithValue:(NSNumber * _Nonnull)value
                                             params:(MTRWriteParams * _Nullable)params
                                         completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::MinHeatSetpointLimit::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.shortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeMinHeatSetpointLimitWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::MinHeatSetpointLimit::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMinHeatSetpointLimitWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::MinHeatSetpointLimit::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMaxHeatSetpointLimitWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::MaxHeatSetpointLimit::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeMaxHeatSetpointLimitWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeMaxHeatSetpointLimitWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeMaxHeatSetpointLimitWithValue:(NSNumber * _Nonnull)value
                                             params:(MTRWriteParams * _Nullable)params
                                         completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::MaxHeatSetpointLimit::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.shortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeMaxHeatSetpointLimitWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::MaxHeatSetpointLimit::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMaxHeatSetpointLimitWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::MaxHeatSetpointLimit::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMinCoolSetpointLimitWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::MinCoolSetpointLimit::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeMinCoolSetpointLimitWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeMinCoolSetpointLimitWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeMinCoolSetpointLimitWithValue:(NSNumber * _Nonnull)value
                                             params:(MTRWriteParams * _Nullable)params
                                         completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::MinCoolSetpointLimit::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.shortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeMinCoolSetpointLimitWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::MinCoolSetpointLimit::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMinCoolSetpointLimitWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::MinCoolSetpointLimit::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMaxCoolSetpointLimitWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::MaxCoolSetpointLimit::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeMaxCoolSetpointLimitWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeMaxCoolSetpointLimitWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeMaxCoolSetpointLimitWithValue:(NSNumber * _Nonnull)value
                                             params:(MTRWriteParams * _Nullable)params
                                         completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::MaxCoolSetpointLimit::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.shortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeMaxCoolSetpointLimitWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::MaxCoolSetpointLimit::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMaxCoolSetpointLimitWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::MaxCoolSetpointLimit::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMinSetpointDeadBandWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::MinSetpointDeadBand::TypeInfo;
    return MTRReadAttribute<MTRInt8sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeMinSetpointDeadBandWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeMinSetpointDeadBandWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeMinSetpointDeadBandWithValue:(NSNumber * _Nonnull)value
                                            params:(MTRWriteParams * _Nullable)params
                                        completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::MinSetpointDeadBand::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.charValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeMinSetpointDeadBandWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::MinSetpointDeadBand::TypeInfo;
    MTRSubscribeAttribute<MTRInt8sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMinSetpointDeadBandWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::MinSetpointDeadBand::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRemoteSensingWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::RemoteSensing::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeRemoteSensingWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeRemoteSensingWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeRemoteSensingWithValue:(NSNumber * _Nonnull)value
                                      params:(MTRWriteParams * _Nullable)params
                                  completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::RemoteSensing::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeRemoteSensingWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::RemoteSensing::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRemoteSensingWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::RemoteSensing::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeControlSequenceOfOperationWithCompletion:(void (^)(
                                                                  NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::ControlSequenceOfOperation::TypeInfo;
    return MTRReadAttribute<MTRThermostatClusterThermostatControlSequenceAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeControlSequenceOfOperationWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeControlSequenceOfOperationWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeControlSequenceOfOperationWithValue:(NSNumber * _Nonnull)value
                                                   params:(MTRWriteParams * _Nullable)params
                                               completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::ControlSequenceOfOperation::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = static_cast<std::remove_reference_t<decltype(cppValue)>>(value.unsignedCharValue);

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeControlSequenceOfOperationWithParams:(MTRSubscribeParams * _Nonnull)params
                                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::ControlSequenceOfOperation::TypeInfo;
    MTRSubscribeAttribute<MTRThermostatClusterThermostatControlSequenceAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeControlSequenceOfOperationWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                            endpoint:(NSNumber *)endpoint
                                                               queue:(dispatch_queue_t)queue
                                                          completion:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completion
{
    auto * bridge = new MTRThermostatClusterThermostatControlSequenceAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ThermostatClusterThermostatControlSequenceAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::ControlSequenceOfOperation::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSystemModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::SystemMode::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeSystemModeWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeSystemModeWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeSystemModeWithValue:(NSNumber * _Nonnull)value
                                   params:(MTRWriteParams * _Nullable)params
                               completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::SystemMode::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeSystemModeWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::SystemMode::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeSystemModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::SystemMode::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeThermostatRunningModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::ThermostatRunningMode::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeThermostatRunningModeWithParams:(MTRSubscribeParams * _Nonnull)params
                                  subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::ThermostatRunningMode::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeThermostatRunningModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                                     completion:
                                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::ThermostatRunningMode::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeStartOfWeekWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::StartOfWeek::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeStartOfWeekWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::StartOfWeek::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeStartOfWeekWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::StartOfWeek::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNumberOfWeeklyTransitionsWithCompletion:(void (^)(
                                                                 NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::NumberOfWeeklyTransitions::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeNumberOfWeeklyTransitionsWithParams:(MTRSubscribeParams * _Nonnull)params
                                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::NumberOfWeeklyTransitions::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNumberOfWeeklyTransitionsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                           endpoint:(NSNumber *)endpoint
                                                              queue:(dispatch_queue_t)queue
                                                         completion:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::NumberOfWeeklyTransitions::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNumberOfDailyTransitionsWithCompletion:(void (^)(
                                                                NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::NumberOfDailyTransitions::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeNumberOfDailyTransitionsWithParams:(MTRSubscribeParams * _Nonnull)params
                                     subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::NumberOfDailyTransitions::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNumberOfDailyTransitionsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                          endpoint:(NSNumber *)endpoint
                                                             queue:(dispatch_queue_t)queue
                                                        completion:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::NumberOfDailyTransitions::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeTemperatureSetpointHoldWithCompletion:(void (^)(
                                                               NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::TemperatureSetpointHold::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeTemperatureSetpointHoldWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeTemperatureSetpointHoldWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeTemperatureSetpointHoldWithValue:(NSNumber * _Nonnull)value
                                                params:(MTRWriteParams * _Nullable)params
                                            completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::TemperatureSetpointHold::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeTemperatureSetpointHoldWithParams:(MTRSubscribeParams * _Nonnull)params
                                    subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::TemperatureSetpointHold::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeTemperatureSetpointHoldWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                         endpoint:(NSNumber *)endpoint
                                                            queue:(dispatch_queue_t)queue
                                                       completion:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::TemperatureSetpointHold::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeTemperatureSetpointHoldDurationWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::TemperatureSetpointHoldDuration::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeTemperatureSetpointHoldDurationWithValue:(NSNumber * _Nullable)value
                                                    completion:(MTRStatusCompletion)completion
{
    [self writeAttributeTemperatureSetpointHoldDurationWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeTemperatureSetpointHoldDurationWithValue:(NSNumber * _Nullable)value
                                                        params:(MTRWriteParams * _Nullable)params
                                                    completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::TemperatureSetpointHoldDuration::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedShortValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeTemperatureSetpointHoldDurationWithParams:(MTRSubscribeParams * _Nonnull)params
                                            subscriptionEstablished:
                                                (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                      reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::TemperatureSetpointHoldDuration::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeTemperatureSetpointHoldDurationWithClusterStateCache:
            (MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                                 endpoint:(NSNumber *)endpoint
                                                                    queue:(dispatch_queue_t)queue
                                                               completion:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::TemperatureSetpointHoldDuration::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeThermostatProgrammingOperationModeWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::ThermostatProgrammingOperationMode::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeThermostatProgrammingOperationModeWithValue:(NSNumber * _Nonnull)value
                                                       completion:(MTRStatusCompletion)completion
{
    [self writeAttributeThermostatProgrammingOperationModeWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeThermostatProgrammingOperationModeWithValue:(NSNumber * _Nonnull)value
                                                           params:(MTRWriteParams * _Nullable)params
                                                       completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::ThermostatProgrammingOperationMode::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeThermostatProgrammingOperationModeWithParams:(MTRSubscribeParams * _Nonnull)params
                                               subscriptionEstablished:
                                                   (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                         reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::ThermostatProgrammingOperationMode::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeThermostatProgrammingOperationModeWithClusterStateCache:
            (MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                                    endpoint:(NSNumber *)endpoint
                                                                       queue:(dispatch_queue_t)queue
                                                                  completion:(void (^)(NSNumber * _Nullable value,
                                                                                 NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::ThermostatProgrammingOperationMode::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeThermostatRunningStateWithCompletion:(void (^)(
                                                              NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::ThermostatRunningState::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeThermostatRunningStateWithParams:(MTRSubscribeParams * _Nonnull)params
                                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::ThermostatRunningState::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeThermostatRunningStateWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                                      completion:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::ThermostatRunningState::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSetpointChangeSourceWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::SetpointChangeSource::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeSetpointChangeSourceWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::SetpointChangeSource::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeSetpointChangeSourceWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::SetpointChangeSource::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSetpointChangeAmountWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::SetpointChangeAmount::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeSetpointChangeAmountWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::SetpointChangeAmount::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeSetpointChangeAmountWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::SetpointChangeAmount::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSetpointChangeSourceTimestampWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::SetpointChangeSourceTimestamp::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeSetpointChangeSourceTimestampWithParams:(MTRSubscribeParams * _Nonnull)params
                                          subscriptionEstablished:
                                              (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                    reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::SetpointChangeSourceTimestamp::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeSetpointChangeSourceTimestampWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                               endpoint:(NSNumber *)endpoint
                                                                  queue:(dispatch_queue_t)queue
                                                             completion:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::SetpointChangeSourceTimestamp::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeOccupiedSetbackWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::OccupiedSetback::TypeInfo;
    return MTRReadAttribute<MTRNullableInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeOccupiedSetbackWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeOccupiedSetbackWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeOccupiedSetbackWithValue:(NSNumber * _Nullable)value
                                        params:(MTRWriteParams * _Nullable)params
                                    completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::OccupiedSetback::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedCharValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeOccupiedSetbackWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::OccupiedSetback::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeOccupiedSetbackWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::OccupiedSetback::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeOccupiedSetbackMinWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::OccupiedSetbackMin::TypeInfo;
    return MTRReadAttribute<MTRNullableInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeOccupiedSetbackMinWithParams:(MTRSubscribeParams * _Nonnull)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::OccupiedSetbackMin::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeOccupiedSetbackMinWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                                  completion:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::OccupiedSetbackMin::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeOccupiedSetbackMaxWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::OccupiedSetbackMax::TypeInfo;
    return MTRReadAttribute<MTRNullableInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeOccupiedSetbackMaxWithParams:(MTRSubscribeParams * _Nonnull)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::OccupiedSetbackMax::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeOccupiedSetbackMaxWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                                  completion:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::OccupiedSetbackMax::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeUnoccupiedSetbackWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::UnoccupiedSetback::TypeInfo;
    return MTRReadAttribute<MTRNullableInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeUnoccupiedSetbackWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeUnoccupiedSetbackWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeUnoccupiedSetbackWithValue:(NSNumber * _Nullable)value
                                          params:(MTRWriteParams * _Nullable)params
                                      completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::UnoccupiedSetback::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedCharValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeUnoccupiedSetbackWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::UnoccupiedSetback::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeUnoccupiedSetbackWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::UnoccupiedSetback::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeUnoccupiedSetbackMinWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::UnoccupiedSetbackMin::TypeInfo;
    return MTRReadAttribute<MTRNullableInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeUnoccupiedSetbackMinWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::UnoccupiedSetbackMin::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeUnoccupiedSetbackMinWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::UnoccupiedSetbackMin::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeUnoccupiedSetbackMaxWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::UnoccupiedSetbackMax::TypeInfo;
    return MTRReadAttribute<MTRNullableInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeUnoccupiedSetbackMaxWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::UnoccupiedSetbackMax::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeUnoccupiedSetbackMaxWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::UnoccupiedSetbackMax::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEmergencyHeatDeltaWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::EmergencyHeatDelta::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeEmergencyHeatDeltaWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeEmergencyHeatDeltaWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeEmergencyHeatDeltaWithValue:(NSNumber * _Nonnull)value
                                           params:(MTRWriteParams * _Nullable)params
                                       completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::EmergencyHeatDelta::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeEmergencyHeatDeltaWithParams:(MTRSubscribeParams * _Nonnull)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::EmergencyHeatDelta::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEmergencyHeatDeltaWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                                  completion:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::EmergencyHeatDelta::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeACTypeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::ACType::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeACTypeWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeACTypeWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeACTypeWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                           completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::ACType::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeACTypeWithParams:(MTRSubscribeParams * _Nonnull)params
                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                             reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::ACType::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeACTypeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                                      completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::ACType::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeACCapacityWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::ACCapacity::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeACCapacityWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeACCapacityWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeACCapacityWithValue:(NSNumber * _Nonnull)value
                                   params:(MTRWriteParams * _Nullable)params
                               completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::ACCapacity::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeACCapacityWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::ACCapacity::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeACCapacityWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::ACCapacity::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeACRefrigerantTypeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::ACRefrigerantType::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeACRefrigerantTypeWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeACRefrigerantTypeWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeACRefrigerantTypeWithValue:(NSNumber * _Nonnull)value
                                          params:(MTRWriteParams * _Nullable)params
                                      completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::ACRefrigerantType::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeACRefrigerantTypeWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::ACRefrigerantType::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeACRefrigerantTypeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::ACRefrigerantType::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeACCompressorTypeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::ACCompressorType::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeACCompressorTypeWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeACCompressorTypeWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeACCompressorTypeWithValue:(NSNumber * _Nonnull)value
                                         params:(MTRWriteParams * _Nullable)params
                                     completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::ACCompressorType::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeACCompressorTypeWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::ACCompressorType::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeACCompressorTypeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::ACCompressorType::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeACErrorCodeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::ACErrorCode::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeACErrorCodeWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeACErrorCodeWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeACErrorCodeWithValue:(NSNumber * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                                completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::ACErrorCode::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedIntValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeACErrorCodeWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::ACErrorCode::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeACErrorCodeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::ACErrorCode::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeACLouverPositionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::ACLouverPosition::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeACLouverPositionWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeACLouverPositionWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeACLouverPositionWithValue:(NSNumber * _Nonnull)value
                                         params:(MTRWriteParams * _Nullable)params
                                     completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::ACLouverPosition::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeACLouverPositionWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::ACLouverPosition::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeACLouverPositionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::ACLouverPosition::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeACCoilTemperatureWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::ACCoilTemperature::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeACCoilTemperatureWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::ACCoilTemperature::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeACCoilTemperatureWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::ACCoilTemperature::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeACCapacityformatWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::ACCapacityformat::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeACCapacityformatWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeACCapacityformatWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeACCapacityformatWithValue:(NSNumber * _Nonnull)value
                                         params:(MTRWriteParams * _Nullable)params
                                     completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::ACCapacityformat::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeACCapacityformatWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::ACCapacityformat::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeACCapacityformatWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::ACCapacityformat::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRThermostatGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRThermostatGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRThermostatGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ThermostatGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRThermostatAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRThermostatAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRThermostatAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ThermostatAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRThermostatEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRThermostatEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRThermostatEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(ThermostatEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRThermostatAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRThermostatAttributeListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRThermostatAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ThermostatAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Thermostat::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Thermostat::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterThermostat (Deprecated)

- (void)setpointRaiseLowerWithParams:(MTRThermostatClusterSetpointRaiseLowerParams *)params
                   completionHandler:(MTRStatusCompletion)completionHandler
{
    [self setpointRaiseLowerWithParams:params completion:completionHandler];
}
- (void)setWeeklyScheduleWithParams:(MTRThermostatClusterSetWeeklyScheduleParams *)params
                  completionHandler:(MTRStatusCompletion)completionHandler
{
    [self setWeeklyScheduleWithParams:params completion:completionHandler];
}
- (void)getWeeklyScheduleWithParams:(MTRThermostatClusterGetWeeklyScheduleParams *)params
                  completionHandler:(void (^)(MTRThermostatClusterGetWeeklyScheduleResponseParams * _Nullable data,
                                        NSError * _Nullable error))completionHandler
{
    [self getWeeklyScheduleWithParams:params
                           completion:^(
                               MTRThermostatClusterGetWeeklyScheduleResponseParams * _Nullable data, NSError * _Nullable error) {
                               // Cast is safe because subclass does not add any selectors.
                               completionHandler(static_cast<MTRThermostatClusterGetWeeklyScheduleResponseParams *>(data), error);
                           }];
}
- (void)clearWeeklyScheduleWithParams:(MTRThermostatClusterClearWeeklyScheduleParams * _Nullable)params
                    completionHandler:(MTRStatusCompletion)completionHandler
{
    [self clearWeeklyScheduleWithParams:params completion:completionHandler];
}
- (void)clearWeeklyScheduleWithCompletionHandler:(MTRStatusCompletion)completionHandler
{
    [self clearWeeklyScheduleWithParams:nil completionHandler:completionHandler];
}

- (void)readAttributeLocalTemperatureWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeLocalTemperatureWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)
    subscribeAttributeLocalTemperatureWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeLocalTemperatureWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributeLocalTemperatureWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLocalTemperatureWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeOutdoorTemperatureWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    [self readAttributeOutdoorTemperatureWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeOutdoorTemperatureWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:
                                        (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeOutdoorTemperatureWithParams:subscribeParams
                                 subscriptionEstablished:subscriptionEstablishedHandler
                                           reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               reportHandler(static_cast<NSNumber *>(value), error);
                                           }];
}
+ (void)readAttributeOutdoorTemperatureWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOutdoorTemperatureWithClusterStateCache:attributeCacheContainer.realContainer
                                                      endpoint:endpoint
                                                         queue:queue
                                                    completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                        // Cast is safe because subclass does not add any selectors.
                                                        completionHandler(static_cast<NSNumber *>(value), error);
                                                    }];
}

- (void)readAttributeOccupancyWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOccupancyWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeOccupancyWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeOccupancyWithParams:subscribeParams
                        subscriptionEstablished:subscriptionEstablishedHandler
                                  reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                      // Cast is safe because subclass does not add any selectors.
                                      reportHandler(static_cast<NSNumber *>(value), error);
                                  }];
}
+ (void)readAttributeOccupancyWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOccupancyWithClusterStateCache:attributeCacheContainer.realContainer
                                             endpoint:endpoint
                                                queue:queue
                                           completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               completionHandler(static_cast<NSNumber *>(value), error);
                                           }];
}

- (void)readAttributeAbsMinHeatSetpointLimitWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    [self readAttributeAbsMinHeatSetpointLimitWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeAbsMinHeatSetpointLimitWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                                          params:(MTRSubscribeParams * _Nullable)params
                                         subscriptionEstablished:
                                             (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                   reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAbsMinHeatSetpointLimitWithParams:subscribeParams
                                      subscriptionEstablished:subscriptionEstablishedHandler
                                                reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    reportHandler(static_cast<NSNumber *>(value), error);
                                                }];
}
+ (void)readAttributeAbsMinHeatSetpointLimitWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                             completionHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAbsMinHeatSetpointLimitWithClusterStateCache:attributeCacheContainer.realContainer
                                                           endpoint:endpoint
                                                              queue:queue
                                                         completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                             // Cast is safe because subclass does not add any selectors.
                                                             completionHandler(static_cast<NSNumber *>(value), error);
                                                         }];
}

- (void)readAttributeAbsMaxHeatSetpointLimitWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    [self readAttributeAbsMaxHeatSetpointLimitWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeAbsMaxHeatSetpointLimitWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                                          params:(MTRSubscribeParams * _Nullable)params
                                         subscriptionEstablished:
                                             (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                   reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAbsMaxHeatSetpointLimitWithParams:subscribeParams
                                      subscriptionEstablished:subscriptionEstablishedHandler
                                                reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    reportHandler(static_cast<NSNumber *>(value), error);
                                                }];
}
+ (void)readAttributeAbsMaxHeatSetpointLimitWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                             completionHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAbsMaxHeatSetpointLimitWithClusterStateCache:attributeCacheContainer.realContainer
                                                           endpoint:endpoint
                                                              queue:queue
                                                         completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                             // Cast is safe because subclass does not add any selectors.
                                                             completionHandler(static_cast<NSNumber *>(value), error);
                                                         }];
}

- (void)readAttributeAbsMinCoolSetpointLimitWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    [self readAttributeAbsMinCoolSetpointLimitWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeAbsMinCoolSetpointLimitWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                                          params:(MTRSubscribeParams * _Nullable)params
                                         subscriptionEstablished:
                                             (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                   reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAbsMinCoolSetpointLimitWithParams:subscribeParams
                                      subscriptionEstablished:subscriptionEstablishedHandler
                                                reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    reportHandler(static_cast<NSNumber *>(value), error);
                                                }];
}
+ (void)readAttributeAbsMinCoolSetpointLimitWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                             completionHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAbsMinCoolSetpointLimitWithClusterStateCache:attributeCacheContainer.realContainer
                                                           endpoint:endpoint
                                                              queue:queue
                                                         completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                             // Cast is safe because subclass does not add any selectors.
                                                             completionHandler(static_cast<NSNumber *>(value), error);
                                                         }];
}

- (void)readAttributeAbsMaxCoolSetpointLimitWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    [self readAttributeAbsMaxCoolSetpointLimitWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeAbsMaxCoolSetpointLimitWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                                          params:(MTRSubscribeParams * _Nullable)params
                                         subscriptionEstablished:
                                             (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                   reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAbsMaxCoolSetpointLimitWithParams:subscribeParams
                                      subscriptionEstablished:subscriptionEstablishedHandler
                                                reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    reportHandler(static_cast<NSNumber *>(value), error);
                                                }];
}
+ (void)readAttributeAbsMaxCoolSetpointLimitWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                             completionHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAbsMaxCoolSetpointLimitWithClusterStateCache:attributeCacheContainer.realContainer
                                                           endpoint:endpoint
                                                              queue:queue
                                                         completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                             // Cast is safe because subclass does not add any selectors.
                                                             completionHandler(static_cast<NSNumber *>(value), error);
                                                         }];
}

- (void)readAttributePICoolingDemandWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributePICoolingDemandWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributePICoolingDemandWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePICoolingDemandWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributePICoolingDemandWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePICoolingDemandWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (void)readAttributePIHeatingDemandWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributePIHeatingDemandWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributePIHeatingDemandWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePIHeatingDemandWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributePIHeatingDemandWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePIHeatingDemandWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (void)readAttributeHVACSystemTypeConfigurationWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))completionHandler
{
    [self readAttributeHVACSystemTypeConfigurationWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeHVACSystemTypeConfigurationWithValue:(NSNumber * _Nonnull)value
                                         completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeHVACSystemTypeConfigurationWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeHVACSystemTypeConfigurationWithValue:(NSNumber * _Nonnull)value
                                                    params:(MTRWriteParams * _Nullable)params
                                         completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeHVACSystemTypeConfigurationWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeHVACSystemTypeConfigurationWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                                              params:(MTRSubscribeParams * _Nullable)params
                                             subscriptionEstablished:
                                                 (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                       reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeHVACSystemTypeConfigurationWithParams:subscribeParams
                                          subscriptionEstablished:subscriptionEstablishedHandler
                                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                        // Cast is safe because subclass does not add any selectors.
                                                        reportHandler(static_cast<NSNumber *>(value), error);
                                                    }];
}
+ (void)readAttributeHVACSystemTypeConfigurationWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                          endpoint:(NSNumber *)endpoint
                                                             queue:(dispatch_queue_t)queue
                                                 completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completionHandler
{
    [self readAttributeHVACSystemTypeConfigurationWithClusterStateCache:attributeCacheContainer.realContainer
                                                               endpoint:endpoint
                                                                  queue:queue
                                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                 // Cast is safe because subclass does not add any selectors.
                                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                                             }];
}

- (void)readAttributeLocalTemperatureCalibrationWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))completionHandler
{
    [self readAttributeLocalTemperatureCalibrationWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeLocalTemperatureCalibrationWithValue:(NSNumber * _Nonnull)value
                                         completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeLocalTemperatureCalibrationWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeLocalTemperatureCalibrationWithValue:(NSNumber * _Nonnull)value
                                                    params:(MTRWriteParams * _Nullable)params
                                         completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeLocalTemperatureCalibrationWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeLocalTemperatureCalibrationWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                                              params:(MTRSubscribeParams * _Nullable)params
                                             subscriptionEstablished:
                                                 (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                       reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeLocalTemperatureCalibrationWithParams:subscribeParams
                                          subscriptionEstablished:subscriptionEstablishedHandler
                                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                        // Cast is safe because subclass does not add any selectors.
                                                        reportHandler(static_cast<NSNumber *>(value), error);
                                                    }];
}
+ (void)readAttributeLocalTemperatureCalibrationWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                          endpoint:(NSNumber *)endpoint
                                                             queue:(dispatch_queue_t)queue
                                                 completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completionHandler
{
    [self readAttributeLocalTemperatureCalibrationWithClusterStateCache:attributeCacheContainer.realContainer
                                                               endpoint:endpoint
                                                                  queue:queue
                                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                 // Cast is safe because subclass does not add any selectors.
                                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                                             }];
}

- (void)readAttributeOccupiedCoolingSetpointWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    [self readAttributeOccupiedCoolingSetpointWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeOccupiedCoolingSetpointWithValue:(NSNumber * _Nonnull)value
                                     completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeOccupiedCoolingSetpointWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeOccupiedCoolingSetpointWithValue:(NSNumber * _Nonnull)value
                                                params:(MTRWriteParams * _Nullable)params
                                     completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeOccupiedCoolingSetpointWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeOccupiedCoolingSetpointWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                                          params:(MTRSubscribeParams * _Nullable)params
                                         subscriptionEstablished:
                                             (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                   reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeOccupiedCoolingSetpointWithParams:subscribeParams
                                      subscriptionEstablished:subscriptionEstablishedHandler
                                                reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    reportHandler(static_cast<NSNumber *>(value), error);
                                                }];
}
+ (void)readAttributeOccupiedCoolingSetpointWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                             completionHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOccupiedCoolingSetpointWithClusterStateCache:attributeCacheContainer.realContainer
                                                           endpoint:endpoint
                                                              queue:queue
                                                         completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                             // Cast is safe because subclass does not add any selectors.
                                                             completionHandler(static_cast<NSNumber *>(value), error);
                                                         }];
}

- (void)readAttributeOccupiedHeatingSetpointWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    [self readAttributeOccupiedHeatingSetpointWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeOccupiedHeatingSetpointWithValue:(NSNumber * _Nonnull)value
                                     completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeOccupiedHeatingSetpointWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeOccupiedHeatingSetpointWithValue:(NSNumber * _Nonnull)value
                                                params:(MTRWriteParams * _Nullable)params
                                     completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeOccupiedHeatingSetpointWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeOccupiedHeatingSetpointWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                                          params:(MTRSubscribeParams * _Nullable)params
                                         subscriptionEstablished:
                                             (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                   reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeOccupiedHeatingSetpointWithParams:subscribeParams
                                      subscriptionEstablished:subscriptionEstablishedHandler
                                                reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    reportHandler(static_cast<NSNumber *>(value), error);
                                                }];
}
+ (void)readAttributeOccupiedHeatingSetpointWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                             completionHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOccupiedHeatingSetpointWithClusterStateCache:attributeCacheContainer.realContainer
                                                           endpoint:endpoint
                                                              queue:queue
                                                         completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                             // Cast is safe because subclass does not add any selectors.
                                                             completionHandler(static_cast<NSNumber *>(value), error);
                                                         }];
}

- (void)readAttributeUnoccupiedCoolingSetpointWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    [self readAttributeUnoccupiedCoolingSetpointWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeUnoccupiedCoolingSetpointWithValue:(NSNumber * _Nonnull)value
                                       completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeUnoccupiedCoolingSetpointWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeUnoccupiedCoolingSetpointWithValue:(NSNumber * _Nonnull)value
                                                  params:(MTRWriteParams * _Nullable)params
                                       completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeUnoccupiedCoolingSetpointWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeUnoccupiedCoolingSetpointWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                                            params:(MTRSubscribeParams * _Nullable)params
                                           subscriptionEstablished:
                                               (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                     reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeUnoccupiedCoolingSetpointWithParams:subscribeParams
                                        subscriptionEstablished:subscriptionEstablishedHandler
                                                  reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      reportHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}
+ (void)readAttributeUnoccupiedCoolingSetpointWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                               completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    [self readAttributeUnoccupiedCoolingSetpointWithClusterStateCache:attributeCacheContainer.realContainer
                                                             endpoint:endpoint
                                                                queue:queue
                                                           completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                               // Cast is safe because subclass does not add any selectors.
                                                               completionHandler(static_cast<NSNumber *>(value), error);
                                                           }];
}

- (void)readAttributeUnoccupiedHeatingSetpointWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    [self readAttributeUnoccupiedHeatingSetpointWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeUnoccupiedHeatingSetpointWithValue:(NSNumber * _Nonnull)value
                                       completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeUnoccupiedHeatingSetpointWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeUnoccupiedHeatingSetpointWithValue:(NSNumber * _Nonnull)value
                                                  params:(MTRWriteParams * _Nullable)params
                                       completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeUnoccupiedHeatingSetpointWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeUnoccupiedHeatingSetpointWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                                            params:(MTRSubscribeParams * _Nullable)params
                                           subscriptionEstablished:
                                               (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                     reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeUnoccupiedHeatingSetpointWithParams:subscribeParams
                                        subscriptionEstablished:subscriptionEstablishedHandler
                                                  reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      reportHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}
+ (void)readAttributeUnoccupiedHeatingSetpointWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                               completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    [self readAttributeUnoccupiedHeatingSetpointWithClusterStateCache:attributeCacheContainer.realContainer
                                                             endpoint:endpoint
                                                                queue:queue
                                                           completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                               // Cast is safe because subclass does not add any selectors.
                                                               completionHandler(static_cast<NSNumber *>(value), error);
                                                           }];
}

- (void)readAttributeMinHeatSetpointLimitWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeMinHeatSetpointLimitWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeMinHeatSetpointLimitWithValue:(NSNumber * _Nonnull)value
                                  completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeMinHeatSetpointLimitWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeMinHeatSetpointLimitWithValue:(NSNumber * _Nonnull)value
                                             params:(MTRWriteParams * _Nullable)params
                                  completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeMinHeatSetpointLimitWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeMinHeatSetpointLimitWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMinHeatSetpointLimitWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSNumber *>(value), error);
                                             }];
}
+ (void)readAttributeMinHeatSetpointLimitWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMinHeatSetpointLimitWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSNumber *>(value), error);
                                                      }];
}

- (void)readAttributeMaxHeatSetpointLimitWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxHeatSetpointLimitWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeMaxHeatSetpointLimitWithValue:(NSNumber * _Nonnull)value
                                  completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeMaxHeatSetpointLimitWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeMaxHeatSetpointLimitWithValue:(NSNumber * _Nonnull)value
                                             params:(MTRWriteParams * _Nullable)params
                                  completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeMaxHeatSetpointLimitWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeMaxHeatSetpointLimitWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMaxHeatSetpointLimitWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSNumber *>(value), error);
                                             }];
}
+ (void)readAttributeMaxHeatSetpointLimitWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxHeatSetpointLimitWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSNumber *>(value), error);
                                                      }];
}

- (void)readAttributeMinCoolSetpointLimitWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeMinCoolSetpointLimitWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeMinCoolSetpointLimitWithValue:(NSNumber * _Nonnull)value
                                  completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeMinCoolSetpointLimitWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeMinCoolSetpointLimitWithValue:(NSNumber * _Nonnull)value
                                             params:(MTRWriteParams * _Nullable)params
                                  completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeMinCoolSetpointLimitWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeMinCoolSetpointLimitWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMinCoolSetpointLimitWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSNumber *>(value), error);
                                             }];
}
+ (void)readAttributeMinCoolSetpointLimitWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMinCoolSetpointLimitWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSNumber *>(value), error);
                                                      }];
}

- (void)readAttributeMaxCoolSetpointLimitWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxCoolSetpointLimitWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeMaxCoolSetpointLimitWithValue:(NSNumber * _Nonnull)value
                                  completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeMaxCoolSetpointLimitWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeMaxCoolSetpointLimitWithValue:(NSNumber * _Nonnull)value
                                             params:(MTRWriteParams * _Nullable)params
                                  completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeMaxCoolSetpointLimitWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeMaxCoolSetpointLimitWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMaxCoolSetpointLimitWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSNumber *>(value), error);
                                             }];
}
+ (void)readAttributeMaxCoolSetpointLimitWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxCoolSetpointLimitWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSNumber *>(value), error);
                                                      }];
}

- (void)readAttributeMinSetpointDeadBandWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeMinSetpointDeadBandWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeMinSetpointDeadBandWithValue:(NSNumber * _Nonnull)value
                                 completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeMinSetpointDeadBandWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeMinSetpointDeadBandWithValue:(NSNumber * _Nonnull)value
                                            params:(MTRWriteParams * _Nullable)params
                                 completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeMinSetpointDeadBandWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeMinSetpointDeadBandWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMinSetpointDeadBandWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSNumber *>(value), error);
                                            }];
}
+ (void)readAttributeMinSetpointDeadBandWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMinSetpointDeadBandWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}

- (void)readAttributeRemoteSensingWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRemoteSensingWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeRemoteSensingWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeRemoteSensingWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeRemoteSensingWithValue:(NSNumber * _Nonnull)value
                                      params:(MTRWriteParams * _Nullable)params
                           completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeRemoteSensingWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeRemoteSensingWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRemoteSensingWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributeRemoteSensingWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRemoteSensingWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributeControlSequenceOfOperationWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    [self readAttributeControlSequenceOfOperationWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeControlSequenceOfOperationWithValue:(NSNumber * _Nonnull)value
                                        completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeControlSequenceOfOperationWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeControlSequenceOfOperationWithValue:(NSNumber * _Nonnull)value
                                                   params:(MTRWriteParams * _Nullable)params
                                        completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeControlSequenceOfOperationWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeControlSequenceOfOperationWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                                             params:(MTRSubscribeParams * _Nullable)params
                                            subscriptionEstablished:
                                                (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                      reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeControlSequenceOfOperationWithParams:subscribeParams
                                         subscriptionEstablished:subscriptionEstablishedHandler
                                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       reportHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}
+ (void)readAttributeControlSequenceOfOperationWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                         endpoint:(NSNumber *)endpoint
                                                            queue:(dispatch_queue_t)queue
                                                completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    [self readAttributeControlSequenceOfOperationWithClusterStateCache:attributeCacheContainer.realContainer
                                                              endpoint:endpoint
                                                                 queue:queue
                                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                // Cast is safe because subclass does not add any selectors.
                                                                completionHandler(static_cast<NSNumber *>(value), error);
                                                            }];
}

- (void)readAttributeSystemModeWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSystemModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeSystemModeWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeSystemModeWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeSystemModeWithValue:(NSNumber * _Nonnull)value
                                   params:(MTRWriteParams * _Nullable)params
                        completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeSystemModeWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeSystemModeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeSystemModeWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeSystemModeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSystemModeWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeThermostatRunningModeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    [self readAttributeThermostatRunningModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeThermostatRunningModeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeThermostatRunningModeWithParams:subscribeParams
                                    subscriptionEstablished:subscriptionEstablishedHandler
                                              reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  reportHandler(static_cast<NSNumber *>(value), error);
                                              }];
}
+ (void)readAttributeThermostatRunningModeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeThermostatRunningModeWithClusterStateCache:attributeCacheContainer.realContainer
                                                         endpoint:endpoint
                                                            queue:queue
                                                       completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                           // Cast is safe because subclass does not add any selectors.
                                                           completionHandler(static_cast<NSNumber *>(value), error);
                                                       }];
}

- (void)readAttributeStartOfWeekWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeStartOfWeekWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeStartOfWeekWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeStartOfWeekWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSNumber *>(value), error);
                                    }];
}
+ (void)readAttributeStartOfWeekWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeStartOfWeekWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                             }];
}

- (void)readAttributeNumberOfWeeklyTransitionsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    [self readAttributeNumberOfWeeklyTransitionsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeNumberOfWeeklyTransitionsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                                            params:(MTRSubscribeParams * _Nullable)params
                                           subscriptionEstablished:
                                               (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                     reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNumberOfWeeklyTransitionsWithParams:subscribeParams
                                        subscriptionEstablished:subscriptionEstablishedHandler
                                                  reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      reportHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}
+ (void)readAttributeNumberOfWeeklyTransitionsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                               completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    [self readAttributeNumberOfWeeklyTransitionsWithClusterStateCache:attributeCacheContainer.realContainer
                                                             endpoint:endpoint
                                                                queue:queue
                                                           completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                               // Cast is safe because subclass does not add any selectors.
                                                               completionHandler(static_cast<NSNumber *>(value), error);
                                                           }];
}

- (void)readAttributeNumberOfDailyTransitionsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completionHandler
{
    [self readAttributeNumberOfDailyTransitionsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeNumberOfDailyTransitionsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                                           params:(MTRSubscribeParams * _Nullable)params
                                          subscriptionEstablished:
                                              (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                    reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNumberOfDailyTransitionsWithParams:subscribeParams
                                       subscriptionEstablished:subscriptionEstablishedHandler
                                                 reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     reportHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}
+ (void)readAttributeNumberOfDailyTransitionsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                              completionHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNumberOfDailyTransitionsWithClusterStateCache:attributeCacheContainer.realContainer
                                                            endpoint:endpoint
                                                               queue:queue
                                                          completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                              // Cast is safe because subclass does not add any selectors.
                                                              completionHandler(static_cast<NSNumber *>(value), error);
                                                          }];
}

- (void)readAttributeTemperatureSetpointHoldWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    [self readAttributeTemperatureSetpointHoldWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeTemperatureSetpointHoldWithValue:(NSNumber * _Nonnull)value
                                     completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeTemperatureSetpointHoldWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeTemperatureSetpointHoldWithValue:(NSNumber * _Nonnull)value
                                                params:(MTRWriteParams * _Nullable)params
                                     completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeTemperatureSetpointHoldWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeTemperatureSetpointHoldWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                                          params:(MTRSubscribeParams * _Nullable)params
                                         subscriptionEstablished:
                                             (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                   reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeTemperatureSetpointHoldWithParams:subscribeParams
                                      subscriptionEstablished:subscriptionEstablishedHandler
                                                reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    reportHandler(static_cast<NSNumber *>(value), error);
                                                }];
}
+ (void)readAttributeTemperatureSetpointHoldWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                             completionHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeTemperatureSetpointHoldWithClusterStateCache:attributeCacheContainer.realContainer
                                                           endpoint:endpoint
                                                              queue:queue
                                                         completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                             // Cast is safe because subclass does not add any selectors.
                                                             completionHandler(static_cast<NSNumber *>(value), error);
                                                         }];
}

- (void)readAttributeTemperatureSetpointHoldDurationWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeTemperatureSetpointHoldDurationWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeTemperatureSetpointHoldDurationWithValue:(NSNumber * _Nullable)value
                                             completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeTemperatureSetpointHoldDurationWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeTemperatureSetpointHoldDurationWithValue:(NSNumber * _Nullable)value
                                                        params:(MTRWriteParams * _Nullable)params
                                             completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeTemperatureSetpointHoldDurationWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeTemperatureSetpointHoldDurationWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                  params:(MTRSubscribeParams * _Nullable)params
                                                 subscriptionEstablished:
                                                     (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                           reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                             NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeTemperatureSetpointHoldDurationWithParams:subscribeParams
                                              subscriptionEstablished:subscriptionEstablishedHandler
                                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                            // Cast is safe because subclass does not add any selectors.
                                                            reportHandler(static_cast<NSNumber *>(value), error);
                                                        }];
}
+ (void)readAttributeTemperatureSetpointHoldDurationWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                              endpoint:(NSNumber *)endpoint
                                                                 queue:(dispatch_queue_t)queue
                                                     completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completionHandler
{
    [self
        readAttributeTemperatureSetpointHoldDurationWithClusterStateCache:attributeCacheContainer.realContainer
                                                                 endpoint:endpoint
                                                                    queue:queue
                                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                   // Cast is safe because subclass does not add any selectors.
                                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                                               }];
}

- (void)readAttributeThermostatProgrammingOperationModeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                 NSError * _Nullable error))completionHandler
{
    [self readAttributeThermostatProgrammingOperationModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeThermostatProgrammingOperationModeWithValue:(NSNumber * _Nonnull)value
                                                completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeThermostatProgrammingOperationModeWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeThermostatProgrammingOperationModeWithValue:(NSNumber * _Nonnull)value
                                                           params:(MTRWriteParams * _Nullable)params
                                                completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeThermostatProgrammingOperationModeWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeThermostatProgrammingOperationModeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                     params:(MTRSubscribeParams * _Nullable)params
                                                    subscriptionEstablished:
                                                        (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                              reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeThermostatProgrammingOperationModeWithParams:subscribeParams
                                                 subscriptionEstablished:subscriptionEstablishedHandler
                                                           reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                               // Cast is safe because subclass does not add any selectors.
                                                               reportHandler(static_cast<NSNumber *>(value), error);
                                                           }];
}
+ (void)readAttributeThermostatProgrammingOperationModeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                                 endpoint:(NSNumber *)endpoint
                                                                    queue:(dispatch_queue_t)queue
                                                        completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeThermostatProgrammingOperationModeWithClusterStateCache:attributeCacheContainer.realContainer
                                                                      endpoint:endpoint
                                                                         queue:queue
                                                                    completion:^(
                                                                        NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                        // Cast is safe because subclass does not add any selectors.
                                                                        completionHandler(static_cast<NSNumber *>(value), error);
                                                                    }];
}

- (void)readAttributeThermostatRunningStateWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    [self readAttributeThermostatRunningStateWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeThermostatRunningStateWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                                         params:(MTRSubscribeParams * _Nullable)params
                                        subscriptionEstablished:
                                            (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeThermostatRunningStateWithParams:subscribeParams
                                     subscriptionEstablished:subscriptionEstablishedHandler
                                               reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   reportHandler(static_cast<NSNumber *>(value), error);
                                               }];
}
+ (void)readAttributeThermostatRunningStateWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                            completionHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeThermostatRunningStateWithClusterStateCache:attributeCacheContainer.realContainer
                                                          endpoint:endpoint
                                                             queue:queue
                                                        completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                            // Cast is safe because subclass does not add any selectors.
                                                            completionHandler(static_cast<NSNumber *>(value), error);
                                                        }];
}

- (void)readAttributeSetpointChangeSourceWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeSetpointChangeSourceWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeSetpointChangeSourceWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeSetpointChangeSourceWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSNumber *>(value), error);
                                             }];
}
+ (void)readAttributeSetpointChangeSourceWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSetpointChangeSourceWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSNumber *>(value), error);
                                                      }];
}

- (void)readAttributeSetpointChangeAmountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeSetpointChangeAmountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeSetpointChangeAmountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeSetpointChangeAmountWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSNumber *>(value), error);
                                             }];
}
+ (void)readAttributeSetpointChangeAmountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSetpointChangeAmountWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSNumber *>(value), error);
                                                      }];
}

- (void)readAttributeSetpointChangeSourceTimestampWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))completionHandler
{
    [self readAttributeSetpointChangeSourceTimestampWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeSetpointChangeSourceTimestampWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                params:(MTRSubscribeParams * _Nullable)params
                                               subscriptionEstablished:
                                                   (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                         reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeSetpointChangeSourceTimestampWithParams:subscribeParams
                                            subscriptionEstablished:subscriptionEstablishedHandler
                                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          reportHandler(static_cast<NSNumber *>(value), error);
                                                      }];
}
+ (void)readAttributeSetpointChangeSourceTimestampWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                            endpoint:(NSNumber *)endpoint
                                                               queue:(dispatch_queue_t)queue
                                                   completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    [self readAttributeSetpointChangeSourceTimestampWithClusterStateCache:attributeCacheContainer.realContainer
                                                                 endpoint:endpoint
                                                                    queue:queue
                                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                   // Cast is safe because subclass does not add any selectors.
                                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                                               }];
}

- (void)readAttributeOccupiedSetbackWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeOccupiedSetbackWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeOccupiedSetbackWithValue:(NSNumber * _Nullable)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeOccupiedSetbackWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeOccupiedSetbackWithValue:(NSNumber * _Nullable)value
                                        params:(MTRWriteParams * _Nullable)params
                             completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeOccupiedSetbackWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeOccupiedSetbackWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeOccupiedSetbackWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeOccupiedSetbackWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOccupiedSetbackWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (void)readAttributeOccupiedSetbackMinWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    [self readAttributeOccupiedSetbackMinWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeOccupiedSetbackMinWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:
                                        (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeOccupiedSetbackMinWithParams:subscribeParams
                                 subscriptionEstablished:subscriptionEstablishedHandler
                                           reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               reportHandler(static_cast<NSNumber *>(value), error);
                                           }];
}
+ (void)readAttributeOccupiedSetbackMinWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOccupiedSetbackMinWithClusterStateCache:attributeCacheContainer.realContainer
                                                      endpoint:endpoint
                                                         queue:queue
                                                    completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                        // Cast is safe because subclass does not add any selectors.
                                                        completionHandler(static_cast<NSNumber *>(value), error);
                                                    }];
}

- (void)readAttributeOccupiedSetbackMaxWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    [self readAttributeOccupiedSetbackMaxWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeOccupiedSetbackMaxWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:
                                        (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeOccupiedSetbackMaxWithParams:subscribeParams
                                 subscriptionEstablished:subscriptionEstablishedHandler
                                           reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               reportHandler(static_cast<NSNumber *>(value), error);
                                           }];
}
+ (void)readAttributeOccupiedSetbackMaxWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOccupiedSetbackMaxWithClusterStateCache:attributeCacheContainer.realContainer
                                                      endpoint:endpoint
                                                         queue:queue
                                                    completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                        // Cast is safe because subclass does not add any selectors.
                                                        completionHandler(static_cast<NSNumber *>(value), error);
                                                    }];
}

- (void)readAttributeUnoccupiedSetbackWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeUnoccupiedSetbackWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeUnoccupiedSetbackWithValue:(NSNumber * _Nullable)value
                               completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeUnoccupiedSetbackWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeUnoccupiedSetbackWithValue:(NSNumber * _Nullable)value
                                          params:(MTRWriteParams * _Nullable)params
                               completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeUnoccupiedSetbackWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeUnoccupiedSetbackWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeUnoccupiedSetbackWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSNumber *>(value), error);
                                          }];
}
+ (void)readAttributeUnoccupiedSetbackWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeUnoccupiedSetbackWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}

- (void)readAttributeUnoccupiedSetbackMinWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeUnoccupiedSetbackMinWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeUnoccupiedSetbackMinWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeUnoccupiedSetbackMinWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSNumber *>(value), error);
                                             }];
}
+ (void)readAttributeUnoccupiedSetbackMinWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeUnoccupiedSetbackMinWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSNumber *>(value), error);
                                                      }];
}

- (void)readAttributeUnoccupiedSetbackMaxWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeUnoccupiedSetbackMaxWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeUnoccupiedSetbackMaxWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeUnoccupiedSetbackMaxWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSNumber *>(value), error);
                                             }];
}
+ (void)readAttributeUnoccupiedSetbackMaxWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeUnoccupiedSetbackMaxWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSNumber *>(value), error);
                                                      }];
}

- (void)readAttributeEmergencyHeatDeltaWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    [self readAttributeEmergencyHeatDeltaWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeEmergencyHeatDeltaWithValue:(NSNumber * _Nonnull)value
                                completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeEmergencyHeatDeltaWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeEmergencyHeatDeltaWithValue:(NSNumber * _Nonnull)value
                                           params:(MTRWriteParams * _Nullable)params
                                completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeEmergencyHeatDeltaWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeEmergencyHeatDeltaWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:
                                        (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeEmergencyHeatDeltaWithParams:subscribeParams
                                 subscriptionEstablished:subscriptionEstablishedHandler
                                           reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               reportHandler(static_cast<NSNumber *>(value), error);
                                           }];
}
+ (void)readAttributeEmergencyHeatDeltaWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeEmergencyHeatDeltaWithClusterStateCache:attributeCacheContainer.realContainer
                                                      endpoint:endpoint
                                                         queue:queue
                                                    completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                        // Cast is safe because subclass does not add any selectors.
                                                        completionHandler(static_cast<NSNumber *>(value), error);
                                                    }];
}

- (void)readAttributeACTypeWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeACTypeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeACTypeWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeACTypeWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeACTypeWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                    completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeACTypeWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeACTypeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeACTypeWithParams:subscribeParams
                     subscriptionEstablished:subscriptionEstablishedHandler
                               reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                   // Cast is safe because subclass does not add any selectors.
                                   reportHandler(static_cast<NSNumber *>(value), error);
                               }];
}
+ (void)readAttributeACTypeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeACTypeWithClusterStateCache:attributeCacheContainer.realContainer
                                          endpoint:endpoint
                                             queue:queue
                                        completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            completionHandler(static_cast<NSNumber *>(value), error);
                                        }];
}

- (void)readAttributeACCapacityWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeACCapacityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeACCapacityWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeACCapacityWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeACCapacityWithValue:(NSNumber * _Nonnull)value
                                   params:(MTRWriteParams * _Nullable)params
                        completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeACCapacityWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeACCapacityWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeACCapacityWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeACCapacityWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeACCapacityWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeACRefrigerantTypeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeACRefrigerantTypeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeACRefrigerantTypeWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeACRefrigerantTypeWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeACRefrigerantTypeWithValue:(NSNumber * _Nonnull)value
                                          params:(MTRWriteParams * _Nullable)params
                               completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeACRefrigerantTypeWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeACRefrigerantTypeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeACRefrigerantTypeWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSNumber *>(value), error);
                                          }];
}
+ (void)readAttributeACRefrigerantTypeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeACRefrigerantTypeWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}

- (void)readAttributeACCompressorTypeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeACCompressorTypeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeACCompressorTypeWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeACCompressorTypeWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeACCompressorTypeWithValue:(NSNumber * _Nonnull)value
                                         params:(MTRWriteParams * _Nullable)params
                              completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeACCompressorTypeWithValue:value params:params completion:completionHandler];
}
- (void)
    subscribeAttributeACCompressorTypeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeACCompressorTypeWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributeACCompressorTypeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeACCompressorTypeWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeACErrorCodeWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeACErrorCodeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeACErrorCodeWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeACErrorCodeWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeACErrorCodeWithValue:(NSNumber * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                         completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeACErrorCodeWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeACErrorCodeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeACErrorCodeWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSNumber *>(value), error);
                                    }];
}
+ (void)readAttributeACErrorCodeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeACErrorCodeWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                             }];
}

- (void)readAttributeACLouverPositionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeACLouverPositionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeACLouverPositionWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeACLouverPositionWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeACLouverPositionWithValue:(NSNumber * _Nonnull)value
                                         params:(MTRWriteParams * _Nullable)params
                              completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeACLouverPositionWithValue:value params:params completion:completionHandler];
}
- (void)
    subscribeAttributeACLouverPositionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeACLouverPositionWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributeACLouverPositionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeACLouverPositionWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeACCoilTemperatureWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeACCoilTemperatureWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeACCoilTemperatureWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeACCoilTemperatureWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSNumber *>(value), error);
                                          }];
}
+ (void)readAttributeACCoilTemperatureWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeACCoilTemperatureWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}

- (void)readAttributeACCapacityformatWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeACCapacityformatWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeACCapacityformatWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeACCapacityformatWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeACCapacityformatWithValue:(NSNumber * _Nonnull)value
                                         params:(MTRWriteParams * _Nullable)params
                              completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeACCapacityformatWithValue:value params:params completion:completionHandler];
}
- (void)
    subscribeAttributeACCapacityformatWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeACCapacityformatWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributeACCapacityformatWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeACCapacityformatWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterFanControl

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)readAttributeFanModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FanControl::Attributes::FanMode::TypeInfo;
    return MTRReadAttribute<MTRFanControlClusterFanModeTypeAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeFanModeWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeFanModeWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeFanModeWithValue:(NSNumber * _Nonnull)value
                                params:(MTRWriteParams * _Nullable)params
                            completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = FanControl::Attributes::FanMode::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = static_cast<std::remove_reference_t<decltype(cppValue)>>(value.unsignedCharValue);

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeFanModeWithParams:(MTRSubscribeParams * _Nonnull)params
                    subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                              reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FanControl::Attributes::FanMode::TypeInfo;
    MTRSubscribeAttribute<MTRFanControlClusterFanModeTypeAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFanModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                       completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRFanControlClusterFanModeTypeAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(FanControlClusterFanModeTypeAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FanControl::Attributes::FanMode::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFanModeSequenceWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FanControl::Attributes::FanModeSequence::TypeInfo;
    return MTRReadAttribute<MTRFanControlClusterFanModeSequenceTypeAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeFanModeSequenceWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeFanModeSequenceWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeFanModeSequenceWithValue:(NSNumber * _Nonnull)value
                                        params:(MTRWriteParams * _Nullable)params
                                    completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = FanControl::Attributes::FanModeSequence::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = static_cast<std::remove_reference_t<decltype(cppValue)>>(value.unsignedCharValue);

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeFanModeSequenceWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FanControl::Attributes::FanModeSequence::TypeInfo;
    MTRSubscribeAttribute<MTRFanControlClusterFanModeSequenceTypeAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeFanModeSequenceWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRFanControlClusterFanModeSequenceTypeAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(FanControlClusterFanModeSequenceTypeAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FanControl::Attributes::FanModeSequence::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePercentSettingWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FanControl::Attributes::PercentSetting::TypeInfo;
    return MTRReadAttribute<MTRNullableInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributePercentSettingWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributePercentSettingWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributePercentSettingWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                                   completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = FanControl::Attributes::PercentSetting::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedCharValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributePercentSettingWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FanControl::Attributes::PercentSetting::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePercentSettingWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FanControl::Attributes::PercentSetting::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePercentCurrentWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FanControl::Attributes::PercentCurrent::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePercentCurrentWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FanControl::Attributes::PercentCurrent::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePercentCurrentWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FanControl::Attributes::PercentCurrent::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSpeedMaxWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FanControl::Attributes::SpeedMax::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeSpeedMaxWithParams:(MTRSubscribeParams * _Nonnull)params
                     subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                               reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FanControl::Attributes::SpeedMax::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeSpeedMaxWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                        completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FanControl::Attributes::SpeedMax::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSpeedSettingWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FanControl::Attributes::SpeedSetting::TypeInfo;
    return MTRReadAttribute<MTRNullableInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeSpeedSettingWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeSpeedSettingWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeSpeedSettingWithValue:(NSNumber * _Nullable)value
                                     params:(MTRWriteParams * _Nullable)params
                                 completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = FanControl::Attributes::SpeedSetting::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedCharValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeSpeedSettingWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FanControl::Attributes::SpeedSetting::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeSpeedSettingWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FanControl::Attributes::SpeedSetting::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSpeedCurrentWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FanControl::Attributes::SpeedCurrent::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeSpeedCurrentWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FanControl::Attributes::SpeedCurrent::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeSpeedCurrentWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FanControl::Attributes::SpeedCurrent::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRockSupportWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FanControl::Attributes::RockSupport::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRockSupportWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FanControl::Attributes::RockSupport::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRockSupportWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FanControl::Attributes::RockSupport::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRockSettingWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FanControl::Attributes::RockSetting::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeRockSettingWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeRockSettingWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeRockSettingWithValue:(NSNumber * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                                completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = FanControl::Attributes::RockSetting::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeRockSettingWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FanControl::Attributes::RockSetting::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRockSettingWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FanControl::Attributes::RockSetting::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeWindSupportWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FanControl::Attributes::WindSupport::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeWindSupportWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FanControl::Attributes::WindSupport::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeWindSupportWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FanControl::Attributes::WindSupport::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeWindSettingWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FanControl::Attributes::WindSetting::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeWindSettingWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeWindSettingWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeWindSettingWithValue:(NSNumber * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                                completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = FanControl::Attributes::WindSetting::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeWindSettingWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FanControl::Attributes::WindSetting::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeWindSettingWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FanControl::Attributes::WindSetting::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FanControl::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRFanControlGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FanControl::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRFanControlGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRFanControlGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(FanControlGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FanControl::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FanControl::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRFanControlAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FanControl::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRFanControlAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRFanControlAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(FanControlAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FanControl::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FanControl::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRFanControlEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FanControl::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRFanControlEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRFanControlEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(FanControlEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FanControl::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FanControl::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRFanControlAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FanControl::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRFanControlAttributeListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRFanControlAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(FanControlAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FanControl::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FanControl::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FanControl::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FanControl::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FanControl::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FanControl::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FanControl::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterFanControl (Deprecated)

- (void)readAttributeFanModeWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFanModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeFanModeWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeFanModeWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeFanModeWithValue:(NSNumber * _Nonnull)value
                                params:(MTRWriteParams * _Nullable)params
                     completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeFanModeWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeFanModeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                          params:(MTRSubscribeParams * _Nullable)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFanModeWithParams:subscribeParams
                      subscriptionEstablished:subscriptionEstablishedHandler
                                reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                    // Cast is safe because subclass does not add any selectors.
                                    reportHandler(static_cast<NSNumber *>(value), error);
                                }];
}
+ (void)readAttributeFanModeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                      endpoint:(NSNumber *)endpoint
                                         queue:(dispatch_queue_t)queue
                             completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFanModeWithClusterStateCache:attributeCacheContainer.realContainer
                                           endpoint:endpoint
                                              queue:queue
                                         completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             completionHandler(static_cast<NSNumber *>(value), error);
                                         }];
}

- (void)readAttributeFanModeSequenceWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeFanModeSequenceWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeFanModeSequenceWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeFanModeSequenceWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeFanModeSequenceWithValue:(NSNumber * _Nonnull)value
                                        params:(MTRWriteParams * _Nullable)params
                             completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeFanModeSequenceWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeFanModeSequenceWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFanModeSequenceWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeFanModeSequenceWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFanModeSequenceWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (void)readAttributePercentSettingWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributePercentSettingWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributePercentSettingWithValue:(NSNumber * _Nullable)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributePercentSettingWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributePercentSettingWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                            completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributePercentSettingWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributePercentSettingWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePercentSettingWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSNumber *>(value), error);
                                       }];
}
+ (void)readAttributePercentSettingWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePercentSettingWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSNumber *>(value), error);
                                                }];
}

- (void)readAttributePercentCurrentWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributePercentCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributePercentCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePercentCurrentWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSNumber *>(value), error);
                                       }];
}
+ (void)readAttributePercentCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePercentCurrentWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSNumber *>(value), error);
                                                }];
}

- (void)readAttributeSpeedMaxWithCompletionHandler:(void (^)(
                                                       NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSpeedMaxWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeSpeedMaxWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeSpeedMaxWithParams:subscribeParams
                       subscriptionEstablished:subscriptionEstablishedHandler
                                 reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                     // Cast is safe because subclass does not add any selectors.
                                     reportHandler(static_cast<NSNumber *>(value), error);
                                 }];
}
+ (void)readAttributeSpeedMaxWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSpeedMaxWithClusterStateCache:attributeCacheContainer.realContainer
                                            endpoint:endpoint
                                               queue:queue
                                          completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              completionHandler(static_cast<NSNumber *>(value), error);
                                          }];
}

- (void)readAttributeSpeedSettingWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSpeedSettingWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeSpeedSettingWithValue:(NSNumber * _Nullable)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeSpeedSettingWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeSpeedSettingWithValue:(NSNumber * _Nullable)value
                                     params:(MTRWriteParams * _Nullable)params
                          completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeSpeedSettingWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeSpeedSettingWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeSpeedSettingWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributeSpeedSettingWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSpeedSettingWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributeSpeedCurrentWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSpeedCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeSpeedCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeSpeedCurrentWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributeSpeedCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSpeedCurrentWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributeRockSupportWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRockSupportWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRockSupportWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRockSupportWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSNumber *>(value), error);
                                    }];
}
+ (void)readAttributeRockSupportWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRockSupportWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                             }];
}

- (void)readAttributeRockSettingWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRockSettingWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeRockSettingWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeRockSettingWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeRockSettingWithValue:(NSNumber * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                         completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeRockSettingWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeRockSettingWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRockSettingWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSNumber *>(value), error);
                                    }];
}
+ (void)readAttributeRockSettingWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRockSettingWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                             }];
}

- (void)readAttributeWindSupportWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeWindSupportWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeWindSupportWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeWindSupportWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSNumber *>(value), error);
                                    }];
}
+ (void)readAttributeWindSupportWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeWindSupportWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                             }];
}

- (void)readAttributeWindSettingWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeWindSettingWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeWindSettingWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeWindSettingWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeWindSettingWithValue:(NSNumber * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                         completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeWindSettingWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeWindSettingWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeWindSettingWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSNumber *>(value), error);
                                    }];
}
+ (void)readAttributeWindSettingWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeWindSettingWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                             }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterThermostatUserInterfaceConfiguration

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)readAttributeTemperatureDisplayModeWithCompletion:(void (^)(
                                                              NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::TemperatureDisplayMode::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeTemperatureDisplayModeWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeTemperatureDisplayModeWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeTemperatureDisplayModeWithValue:(NSNumber * _Nonnull)value
                                               params:(MTRWriteParams * _Nullable)params
                                           completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::TemperatureDisplayMode::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeTemperatureDisplayModeWithParams:(MTRSubscribeParams * _Nonnull)params
                                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::TemperatureDisplayMode::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeTemperatureDisplayModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                                      completion:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::TemperatureDisplayMode::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeKeypadLockoutWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::KeypadLockout::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeKeypadLockoutWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeKeypadLockoutWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeKeypadLockoutWithValue:(NSNumber * _Nonnull)value
                                      params:(MTRWriteParams * _Nullable)params
                                  completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::KeypadLockout::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeKeypadLockoutWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::KeypadLockout::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeKeypadLockoutWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::KeypadLockout::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeScheduleProgrammingVisibilityWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::ScheduleProgrammingVisibility::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeScheduleProgrammingVisibilityWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeScheduleProgrammingVisibilityWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeScheduleProgrammingVisibilityWithValue:(NSNumber * _Nonnull)value
                                                      params:(MTRWriteParams * _Nullable)params
                                                  completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::ScheduleProgrammingVisibility::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeScheduleProgrammingVisibilityWithParams:(MTRSubscribeParams * _Nonnull)params
                                          subscriptionEstablished:
                                              (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                    reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::ScheduleProgrammingVisibility::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeScheduleProgrammingVisibilityWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                               endpoint:(NSNumber *)endpoint
                                                                  queue:(dispatch_queue_t)queue
                                                             completion:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::ScheduleProgrammingVisibility::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRThermostatUserInterfaceConfigurationGeneratedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRThermostatUserInterfaceConfigurationGeneratedCommandListListAttributeCallbackSubscriptionBridge,
        NSArray, TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device,
        self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRThermostatUserInterfaceConfigurationGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ThermostatUserInterfaceConfigurationGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRThermostatUserInterfaceConfigurationAcceptedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRThermostatUserInterfaceConfigurationAcceptedCommandListListAttributeCallbackSubscriptionBridge,
        NSArray, TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device,
        self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRThermostatUserInterfaceConfigurationAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ThermostatUserInterfaceConfigurationAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRThermostatUserInterfaceConfigurationEventListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRThermostatUserInterfaceConfigurationEventListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRThermostatUserInterfaceConfigurationEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ThermostatUserInterfaceConfigurationEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRThermostatUserInterfaceConfigurationAttributeListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRThermostatUserInterfaceConfigurationAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRThermostatUserInterfaceConfigurationAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ThermostatUserInterfaceConfigurationAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterThermostatUserInterfaceConfiguration (Deprecated)

- (void)readAttributeTemperatureDisplayModeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    [self readAttributeTemperatureDisplayModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeTemperatureDisplayModeWithValue:(NSNumber * _Nonnull)value
                                    completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeTemperatureDisplayModeWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeTemperatureDisplayModeWithValue:(NSNumber * _Nonnull)value
                                               params:(MTRWriteParams * _Nullable)params
                                    completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeTemperatureDisplayModeWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeTemperatureDisplayModeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                                         params:(MTRSubscribeParams * _Nullable)params
                                        subscriptionEstablished:
                                            (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeTemperatureDisplayModeWithParams:subscribeParams
                                     subscriptionEstablished:subscriptionEstablishedHandler
                                               reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   reportHandler(static_cast<NSNumber *>(value), error);
                                               }];
}
+ (void)readAttributeTemperatureDisplayModeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                            completionHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeTemperatureDisplayModeWithClusterStateCache:attributeCacheContainer.realContainer
                                                          endpoint:endpoint
                                                             queue:queue
                                                        completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                            // Cast is safe because subclass does not add any selectors.
                                                            completionHandler(static_cast<NSNumber *>(value), error);
                                                        }];
}

- (void)readAttributeKeypadLockoutWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeKeypadLockoutWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeKeypadLockoutWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeKeypadLockoutWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeKeypadLockoutWithValue:(NSNumber * _Nonnull)value
                                      params:(MTRWriteParams * _Nullable)params
                           completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeKeypadLockoutWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeKeypadLockoutWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeKeypadLockoutWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributeKeypadLockoutWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeKeypadLockoutWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributeScheduleProgrammingVisibilityWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))completionHandler
{
    [self readAttributeScheduleProgrammingVisibilityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeScheduleProgrammingVisibilityWithValue:(NSNumber * _Nonnull)value
                                           completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeScheduleProgrammingVisibilityWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeScheduleProgrammingVisibilityWithValue:(NSNumber * _Nonnull)value
                                                      params:(MTRWriteParams * _Nullable)params
                                           completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeScheduleProgrammingVisibilityWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeScheduleProgrammingVisibilityWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                params:(MTRSubscribeParams * _Nullable)params
                                               subscriptionEstablished:
                                                   (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                         reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeScheduleProgrammingVisibilityWithParams:subscribeParams
                                            subscriptionEstablished:subscriptionEstablishedHandler
                                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          reportHandler(static_cast<NSNumber *>(value), error);
                                                      }];
}
+ (void)readAttributeScheduleProgrammingVisibilityWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                            endpoint:(NSNumber *)endpoint
                                                               queue:(dispatch_queue_t)queue
                                                   completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    [self readAttributeScheduleProgrammingVisibilityWithClusterStateCache:attributeCacheContainer.realContainer
                                                                 endpoint:endpoint
                                                                    queue:queue
                                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                   // Cast is safe because subclass does not add any selectors.
                                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                                               }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterColorControl

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)moveToHueWithParams:(MTRColorControlClusterMoveToHueParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            ColorControl::Commands::MoveToHue::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.hue = params.hue.unsignedCharValue;
            request.direction
                = static_cast<std::remove_reference_t<decltype(request.direction)>>(params.direction.unsignedCharValue);
            request.transitionTime = params.transitionTime.unsignedShortValue;
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)moveHueWithParams:(MTRColorControlClusterMoveHueParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            ColorControl::Commands::MoveHue::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.moveMode = static_cast<std::remove_reference_t<decltype(request.moveMode)>>(params.moveMode.unsignedCharValue);
            request.rate = params.rate.unsignedCharValue;
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)stepHueWithParams:(MTRColorControlClusterStepHueParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            ColorControl::Commands::StepHue::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.stepMode = static_cast<std::remove_reference_t<decltype(request.stepMode)>>(params.stepMode.unsignedCharValue);
            request.stepSize = params.stepSize.unsignedCharValue;
            request.transitionTime = params.transitionTime.unsignedCharValue;
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)moveToSaturationWithParams:(MTRColorControlClusterMoveToSaturationParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            ColorControl::Commands::MoveToSaturation::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.saturation = params.saturation.unsignedCharValue;
            request.transitionTime = params.transitionTime.unsignedShortValue;
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)moveSaturationWithParams:(MTRColorControlClusterMoveSaturationParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            ColorControl::Commands::MoveSaturation::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.moveMode = static_cast<std::remove_reference_t<decltype(request.moveMode)>>(params.moveMode.unsignedCharValue);
            request.rate = params.rate.unsignedCharValue;
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)stepSaturationWithParams:(MTRColorControlClusterStepSaturationParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            ColorControl::Commands::StepSaturation::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.stepMode = static_cast<std::remove_reference_t<decltype(request.stepMode)>>(params.stepMode.unsignedCharValue);
            request.stepSize = params.stepSize.unsignedCharValue;
            request.transitionTime = params.transitionTime.unsignedCharValue;
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)moveToHueAndSaturationWithParams:(MTRColorControlClusterMoveToHueAndSaturationParams *)params
                              completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            ColorControl::Commands::MoveToHueAndSaturation::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.hue = params.hue.unsignedCharValue;
            request.saturation = params.saturation.unsignedCharValue;
            request.transitionTime = params.transitionTime.unsignedShortValue;
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)moveToColorWithParams:(MTRColorControlClusterMoveToColorParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            ColorControl::Commands::MoveToColor::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.colorX = params.colorX.unsignedShortValue;
            request.colorY = params.colorY.unsignedShortValue;
            request.transitionTime = params.transitionTime.unsignedShortValue;
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)moveColorWithParams:(MTRColorControlClusterMoveColorParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            ColorControl::Commands::MoveColor::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.rateX = params.rateX.shortValue;
            request.rateY = params.rateY.shortValue;
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)stepColorWithParams:(MTRColorControlClusterStepColorParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            ColorControl::Commands::StepColor::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.stepX = params.stepX.shortValue;
            request.stepY = params.stepY.shortValue;
            request.transitionTime = params.transitionTime.unsignedShortValue;
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)moveToColorTemperatureWithParams:(MTRColorControlClusterMoveToColorTemperatureParams *)params
                              completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            ColorControl::Commands::MoveToColorTemperature::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.colorTemperatureMireds = params.colorTemperatureMireds.unsignedShortValue;
            request.transitionTime = params.transitionTime.unsignedShortValue;
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)enhancedMoveToHueWithParams:(MTRColorControlClusterEnhancedMoveToHueParams *)params
                         completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            ColorControl::Commands::EnhancedMoveToHue::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.enhancedHue = params.enhancedHue.unsignedShortValue;
            request.direction
                = static_cast<std::remove_reference_t<decltype(request.direction)>>(params.direction.unsignedCharValue);
            request.transitionTime = params.transitionTime.unsignedShortValue;
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)enhancedMoveHueWithParams:(MTRColorControlClusterEnhancedMoveHueParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            ColorControl::Commands::EnhancedMoveHue::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.moveMode = static_cast<std::remove_reference_t<decltype(request.moveMode)>>(params.moveMode.unsignedCharValue);
            request.rate = params.rate.unsignedShortValue;
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)enhancedStepHueWithParams:(MTRColorControlClusterEnhancedStepHueParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            ColorControl::Commands::EnhancedStepHue::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.stepMode = static_cast<std::remove_reference_t<decltype(request.stepMode)>>(params.stepMode.unsignedCharValue);
            request.stepSize = params.stepSize.unsignedShortValue;
            request.transitionTime = params.transitionTime.unsignedShortValue;
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)enhancedMoveToHueAndSaturationWithParams:(MTRColorControlClusterEnhancedMoveToHueAndSaturationParams *)params
                                      completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            ColorControl::Commands::EnhancedMoveToHueAndSaturation::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.enhancedHue = params.enhancedHue.unsignedShortValue;
            request.saturation = params.saturation.unsignedCharValue;
            request.transitionTime = params.transitionTime.unsignedShortValue;
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)colorLoopSetWithParams:(MTRColorControlClusterColorLoopSetParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            ColorControl::Commands::ColorLoopSet::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.updateFlags
                = static_cast<std::remove_reference_t<decltype(request.updateFlags)>>(params.updateFlags.unsignedCharValue);
            request.action = static_cast<std::remove_reference_t<decltype(request.action)>>(params.action.unsignedCharValue);
            request.direction
                = static_cast<std::remove_reference_t<decltype(request.direction)>>(params.direction.unsignedCharValue);
            request.time = params.time.unsignedShortValue;
            request.startHue = params.startHue.unsignedShortValue;
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)stopMoveStepWithParams:(MTRColorControlClusterStopMoveStepParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            ColorControl::Commands::StopMoveStep::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)moveColorTemperatureWithParams:(MTRColorControlClusterMoveColorTemperatureParams *)params
                            completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            ColorControl::Commands::MoveColorTemperature::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.moveMode = static_cast<std::remove_reference_t<decltype(request.moveMode)>>(params.moveMode.unsignedCharValue);
            request.rate = params.rate.unsignedShortValue;
            request.colorTemperatureMinimumMireds = params.colorTemperatureMinimumMireds.unsignedShortValue;
            request.colorTemperatureMaximumMireds = params.colorTemperatureMaximumMireds.unsignedShortValue;
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)stepColorTemperatureWithParams:(MTRColorControlClusterStepColorTemperatureParams *)params
                            completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            ColorControl::Commands::StepColorTemperature::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.stepMode = static_cast<std::remove_reference_t<decltype(request.stepMode)>>(params.stepMode.unsignedCharValue);
            request.stepSize = params.stepSize.unsignedShortValue;
            request.transitionTime = params.transitionTime.unsignedShortValue;
            request.colorTemperatureMinimumMireds = params.colorTemperatureMinimumMireds.unsignedShortValue;
            request.colorTemperatureMaximumMireds = params.colorTemperatureMaximumMireds.unsignedShortValue;
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeCurrentHueWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::CurrentHue::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeCurrentHueWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::CurrentHue::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeCurrentHueWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::CurrentHue::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCurrentSaturationWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::CurrentSaturation::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeCurrentSaturationWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::CurrentSaturation::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeCurrentSaturationWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::CurrentSaturation::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRemainingTimeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::RemainingTime::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRemainingTimeWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::RemainingTime::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRemainingTimeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::RemainingTime::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCurrentXWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::CurrentX::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeCurrentXWithParams:(MTRSubscribeParams * _Nonnull)params
                     subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                               reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::CurrentX::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeCurrentXWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                        completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::CurrentX::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCurrentYWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::CurrentY::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeCurrentYWithParams:(MTRSubscribeParams * _Nonnull)params
                     subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                               reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::CurrentY::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeCurrentYWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                        completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::CurrentY::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeDriftCompensationWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::DriftCompensation::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeDriftCompensationWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::DriftCompensation::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeDriftCompensationWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::DriftCompensation::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCompensationTextWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::CompensationText::TypeInfo;
    return MTRReadAttribute<MTRCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeCompensationTextWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::CompensationText::TypeInfo;
    MTRSubscribeAttribute<MTRCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeCompensationTextWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(CharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::CompensationText::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeColorTemperatureMiredsWithCompletion:(void (^)(
                                                              NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::ColorTemperatureMireds::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeColorTemperatureMiredsWithParams:(MTRSubscribeParams * _Nonnull)params
                                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::ColorTemperatureMireds::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeColorTemperatureMiredsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                                      completion:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::ColorTemperatureMireds::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeColorModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::ColorMode::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeColorModeWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::ColorMode::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeColorModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::ColorMode::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeOptionsWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::Options::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeOptionsWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeOptionsWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeOptionsWithValue:(NSNumber * _Nonnull)value
                                params:(MTRWriteParams * _Nullable)params
                            completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ColorControl::Attributes::Options::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeOptionsWithParams:(MTRSubscribeParams * _Nonnull)params
                    subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                              reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::Options::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeOptionsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                       completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::Options::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNumberOfPrimariesWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::NumberOfPrimaries::TypeInfo;
    return MTRReadAttribute<MTRNullableInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeNumberOfPrimariesWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::NumberOfPrimaries::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNumberOfPrimariesWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::NumberOfPrimaries::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePrimary1XWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::Primary1X::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePrimary1XWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::Primary1X::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePrimary1XWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::Primary1X::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePrimary1YWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::Primary1Y::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePrimary1YWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::Primary1Y::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePrimary1YWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::Primary1Y::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePrimary1IntensityWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::Primary1Intensity::TypeInfo;
    return MTRReadAttribute<MTRNullableInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePrimary1IntensityWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::Primary1Intensity::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePrimary1IntensityWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::Primary1Intensity::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePrimary2XWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::Primary2X::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePrimary2XWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::Primary2X::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePrimary2XWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::Primary2X::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePrimary2YWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::Primary2Y::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePrimary2YWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::Primary2Y::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePrimary2YWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::Primary2Y::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePrimary2IntensityWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::Primary2Intensity::TypeInfo;
    return MTRReadAttribute<MTRNullableInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePrimary2IntensityWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::Primary2Intensity::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePrimary2IntensityWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::Primary2Intensity::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePrimary3XWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::Primary3X::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePrimary3XWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::Primary3X::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePrimary3XWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::Primary3X::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePrimary3YWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::Primary3Y::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePrimary3YWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::Primary3Y::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePrimary3YWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::Primary3Y::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePrimary3IntensityWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::Primary3Intensity::TypeInfo;
    return MTRReadAttribute<MTRNullableInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePrimary3IntensityWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::Primary3Intensity::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePrimary3IntensityWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::Primary3Intensity::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePrimary4XWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::Primary4X::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePrimary4XWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::Primary4X::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePrimary4XWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::Primary4X::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePrimary4YWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::Primary4Y::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePrimary4YWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::Primary4Y::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePrimary4YWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::Primary4Y::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePrimary4IntensityWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::Primary4Intensity::TypeInfo;
    return MTRReadAttribute<MTRNullableInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePrimary4IntensityWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::Primary4Intensity::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePrimary4IntensityWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::Primary4Intensity::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePrimary5XWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::Primary5X::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePrimary5XWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::Primary5X::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePrimary5XWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::Primary5X::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePrimary5YWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::Primary5Y::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePrimary5YWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::Primary5Y::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePrimary5YWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::Primary5Y::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePrimary5IntensityWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::Primary5Intensity::TypeInfo;
    return MTRReadAttribute<MTRNullableInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePrimary5IntensityWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::Primary5Intensity::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePrimary5IntensityWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::Primary5Intensity::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePrimary6XWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::Primary6X::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePrimary6XWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::Primary6X::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePrimary6XWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::Primary6X::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePrimary6YWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::Primary6Y::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePrimary6YWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::Primary6Y::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePrimary6YWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::Primary6Y::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePrimary6IntensityWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::Primary6Intensity::TypeInfo;
    return MTRReadAttribute<MTRNullableInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePrimary6IntensityWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::Primary6Intensity::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePrimary6IntensityWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::Primary6Intensity::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeWhitePointXWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::WhitePointX::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeWhitePointXWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeWhitePointXWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeWhitePointXWithValue:(NSNumber * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                                completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ColorControl::Attributes::WhitePointX::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeWhitePointXWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::WhitePointX::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeWhitePointXWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::WhitePointX::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeWhitePointYWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::WhitePointY::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeWhitePointYWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeWhitePointYWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeWhitePointYWithValue:(NSNumber * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                                completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ColorControl::Attributes::WhitePointY::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeWhitePointYWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::WhitePointY::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeWhitePointYWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::WhitePointY::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeColorPointRXWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::ColorPointRX::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeColorPointRXWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeColorPointRXWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeColorPointRXWithValue:(NSNumber * _Nonnull)value
                                     params:(MTRWriteParams * _Nullable)params
                                 completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ColorControl::Attributes::ColorPointRX::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeColorPointRXWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::ColorPointRX::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeColorPointRXWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::ColorPointRX::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeColorPointRYWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::ColorPointRY::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeColorPointRYWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeColorPointRYWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeColorPointRYWithValue:(NSNumber * _Nonnull)value
                                     params:(MTRWriteParams * _Nullable)params
                                 completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ColorControl::Attributes::ColorPointRY::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeColorPointRYWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::ColorPointRY::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeColorPointRYWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::ColorPointRY::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeColorPointRIntensityWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::ColorPointRIntensity::TypeInfo;
    return MTRReadAttribute<MTRNullableInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeColorPointRIntensityWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeColorPointRIntensityWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeColorPointRIntensityWithValue:(NSNumber * _Nullable)value
                                             params:(MTRWriteParams * _Nullable)params
                                         completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ColorControl::Attributes::ColorPointRIntensity::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedCharValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeColorPointRIntensityWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::ColorPointRIntensity::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeColorPointRIntensityWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::ColorPointRIntensity::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeColorPointGXWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::ColorPointGX::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeColorPointGXWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeColorPointGXWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeColorPointGXWithValue:(NSNumber * _Nonnull)value
                                     params:(MTRWriteParams * _Nullable)params
                                 completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ColorControl::Attributes::ColorPointGX::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeColorPointGXWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::ColorPointGX::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeColorPointGXWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::ColorPointGX::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeColorPointGYWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::ColorPointGY::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeColorPointGYWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeColorPointGYWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeColorPointGYWithValue:(NSNumber * _Nonnull)value
                                     params:(MTRWriteParams * _Nullable)params
                                 completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ColorControl::Attributes::ColorPointGY::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeColorPointGYWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::ColorPointGY::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeColorPointGYWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::ColorPointGY::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeColorPointGIntensityWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::ColorPointGIntensity::TypeInfo;
    return MTRReadAttribute<MTRNullableInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeColorPointGIntensityWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeColorPointGIntensityWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeColorPointGIntensityWithValue:(NSNumber * _Nullable)value
                                             params:(MTRWriteParams * _Nullable)params
                                         completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ColorControl::Attributes::ColorPointGIntensity::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedCharValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeColorPointGIntensityWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::ColorPointGIntensity::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeColorPointGIntensityWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::ColorPointGIntensity::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeColorPointBXWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::ColorPointBX::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeColorPointBXWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeColorPointBXWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeColorPointBXWithValue:(NSNumber * _Nonnull)value
                                     params:(MTRWriteParams * _Nullable)params
                                 completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ColorControl::Attributes::ColorPointBX::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeColorPointBXWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::ColorPointBX::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeColorPointBXWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::ColorPointBX::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeColorPointBYWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::ColorPointBY::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeColorPointBYWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeColorPointBYWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeColorPointBYWithValue:(NSNumber * _Nonnull)value
                                     params:(MTRWriteParams * _Nullable)params
                                 completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ColorControl::Attributes::ColorPointBY::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeColorPointBYWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::ColorPointBY::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeColorPointBYWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::ColorPointBY::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeColorPointBIntensityWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::ColorPointBIntensity::TypeInfo;
    return MTRReadAttribute<MTRNullableInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeColorPointBIntensityWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeColorPointBIntensityWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeColorPointBIntensityWithValue:(NSNumber * _Nullable)value
                                             params:(MTRWriteParams * _Nullable)params
                                         completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ColorControl::Attributes::ColorPointBIntensity::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedCharValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeColorPointBIntensityWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::ColorPointBIntensity::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeColorPointBIntensityWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::ColorPointBIntensity::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEnhancedCurrentHueWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::EnhancedCurrentHue::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEnhancedCurrentHueWithParams:(MTRSubscribeParams * _Nonnull)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::EnhancedCurrentHue::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEnhancedCurrentHueWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                                  completion:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::EnhancedCurrentHue::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEnhancedColorModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::EnhancedColorMode::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEnhancedColorModeWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::EnhancedColorMode::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEnhancedColorModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::EnhancedColorMode::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeColorLoopActiveWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::ColorLoopActive::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeColorLoopActiveWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::ColorLoopActive::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeColorLoopActiveWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::ColorLoopActive::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeColorLoopDirectionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::ColorLoopDirection::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeColorLoopDirectionWithParams:(MTRSubscribeParams * _Nonnull)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::ColorLoopDirection::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeColorLoopDirectionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                                  completion:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::ColorLoopDirection::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeColorLoopTimeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::ColorLoopTime::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeColorLoopTimeWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::ColorLoopTime::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeColorLoopTimeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::ColorLoopTime::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeColorLoopStartEnhancedHueWithCompletion:(void (^)(
                                                                 NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::ColorLoopStartEnhancedHue::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeColorLoopStartEnhancedHueWithParams:(MTRSubscribeParams * _Nonnull)params
                                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::ColorLoopStartEnhancedHue::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeColorLoopStartEnhancedHueWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                           endpoint:(NSNumber *)endpoint
                                                              queue:(dispatch_queue_t)queue
                                                         completion:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::ColorLoopStartEnhancedHue::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeColorLoopStoredEnhancedHueWithCompletion:(void (^)(
                                                                  NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::ColorLoopStoredEnhancedHue::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeColorLoopStoredEnhancedHueWithParams:(MTRSubscribeParams * _Nonnull)params
                                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::ColorLoopStoredEnhancedHue::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeColorLoopStoredEnhancedHueWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                            endpoint:(NSNumber *)endpoint
                                                               queue:(dispatch_queue_t)queue
                                                          completion:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::ColorLoopStoredEnhancedHue::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeColorCapabilitiesWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::ColorCapabilities::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeColorCapabilitiesWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::ColorCapabilities::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeColorCapabilitiesWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::ColorCapabilities::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeColorTempPhysicalMinMiredsWithCompletion:(void (^)(
                                                                  NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::ColorTempPhysicalMinMireds::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeColorTempPhysicalMinMiredsWithParams:(MTRSubscribeParams * _Nonnull)params
                                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::ColorTempPhysicalMinMireds::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeColorTempPhysicalMinMiredsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                            endpoint:(NSNumber *)endpoint
                                                               queue:(dispatch_queue_t)queue
                                                          completion:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::ColorTempPhysicalMinMireds::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeColorTempPhysicalMaxMiredsWithCompletion:(void (^)(
                                                                  NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::ColorTempPhysicalMaxMireds::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeColorTempPhysicalMaxMiredsWithParams:(MTRSubscribeParams * _Nonnull)params
                                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::ColorTempPhysicalMaxMireds::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeColorTempPhysicalMaxMiredsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                            endpoint:(NSNumber *)endpoint
                                                               queue:(dispatch_queue_t)queue
                                                          completion:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::ColorTempPhysicalMaxMireds::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCoupleColorTempToLevelMinMiredsWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::CoupleColorTempToLevelMinMireds::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeCoupleColorTempToLevelMinMiredsWithParams:(MTRSubscribeParams * _Nonnull)params
                                            subscriptionEstablished:
                                                (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                      reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::CoupleColorTempToLevelMinMireds::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeCoupleColorTempToLevelMinMiredsWithClusterStateCache:
            (MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                                 endpoint:(NSNumber *)endpoint
                                                                    queue:(dispatch_queue_t)queue
                                                               completion:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::CoupleColorTempToLevelMinMireds::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeStartUpColorTemperatureMiredsWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::StartUpColorTemperatureMireds::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeStartUpColorTemperatureMiredsWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeStartUpColorTemperatureMiredsWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeStartUpColorTemperatureMiredsWithValue:(NSNumber * _Nullable)value
                                                      params:(MTRWriteParams * _Nullable)params
                                                  completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ColorControl::Attributes::StartUpColorTemperatureMireds::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedShortValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeStartUpColorTemperatureMiredsWithParams:(MTRSubscribeParams * _Nonnull)params
                                          subscriptionEstablished:
                                              (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                    reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::StartUpColorTemperatureMireds::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeStartUpColorTemperatureMiredsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                               endpoint:(NSNumber *)endpoint
                                                                  queue:(dispatch_queue_t)queue
                                                             completion:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::StartUpColorTemperatureMireds::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRColorControlGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRColorControlGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRColorControlGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ColorControlGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRColorControlAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRColorControlAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRColorControlAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ColorControlAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRColorControlEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRColorControlEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRColorControlEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(ColorControlEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRColorControlAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRColorControlAttributeListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRColorControlAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ColorControlAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ColorControl::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ColorControl::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterColorControl (Deprecated)

- (void)moveToHueWithParams:(MTRColorControlClusterMoveToHueParams *)params completionHandler:(MTRStatusCompletion)completionHandler
{
    [self moveToHueWithParams:params completion:completionHandler];
}
- (void)moveHueWithParams:(MTRColorControlClusterMoveHueParams *)params completionHandler:(MTRStatusCompletion)completionHandler
{
    [self moveHueWithParams:params completion:completionHandler];
}
- (void)stepHueWithParams:(MTRColorControlClusterStepHueParams *)params completionHandler:(MTRStatusCompletion)completionHandler
{
    [self stepHueWithParams:params completion:completionHandler];
}
- (void)moveToSaturationWithParams:(MTRColorControlClusterMoveToSaturationParams *)params
                 completionHandler:(MTRStatusCompletion)completionHandler
{
    [self moveToSaturationWithParams:params completion:completionHandler];
}
- (void)moveSaturationWithParams:(MTRColorControlClusterMoveSaturationParams *)params
               completionHandler:(MTRStatusCompletion)completionHandler
{
    [self moveSaturationWithParams:params completion:completionHandler];
}
- (void)stepSaturationWithParams:(MTRColorControlClusterStepSaturationParams *)params
               completionHandler:(MTRStatusCompletion)completionHandler
{
    [self stepSaturationWithParams:params completion:completionHandler];
}
- (void)moveToHueAndSaturationWithParams:(MTRColorControlClusterMoveToHueAndSaturationParams *)params
                       completionHandler:(MTRStatusCompletion)completionHandler
{
    [self moveToHueAndSaturationWithParams:params completion:completionHandler];
}
- (void)moveToColorWithParams:(MTRColorControlClusterMoveToColorParams *)params
            completionHandler:(MTRStatusCompletion)completionHandler
{
    [self moveToColorWithParams:params completion:completionHandler];
}
- (void)moveColorWithParams:(MTRColorControlClusterMoveColorParams *)params completionHandler:(MTRStatusCompletion)completionHandler
{
    [self moveColorWithParams:params completion:completionHandler];
}
- (void)stepColorWithParams:(MTRColorControlClusterStepColorParams *)params completionHandler:(MTRStatusCompletion)completionHandler
{
    [self stepColorWithParams:params completion:completionHandler];
}
- (void)moveToColorTemperatureWithParams:(MTRColorControlClusterMoveToColorTemperatureParams *)params
                       completionHandler:(MTRStatusCompletion)completionHandler
{
    [self moveToColorTemperatureWithParams:params completion:completionHandler];
}
- (void)enhancedMoveToHueWithParams:(MTRColorControlClusterEnhancedMoveToHueParams *)params
                  completionHandler:(MTRStatusCompletion)completionHandler
{
    [self enhancedMoveToHueWithParams:params completion:completionHandler];
}
- (void)enhancedMoveHueWithParams:(MTRColorControlClusterEnhancedMoveHueParams *)params
                completionHandler:(MTRStatusCompletion)completionHandler
{
    [self enhancedMoveHueWithParams:params completion:completionHandler];
}
- (void)enhancedStepHueWithParams:(MTRColorControlClusterEnhancedStepHueParams *)params
                completionHandler:(MTRStatusCompletion)completionHandler
{
    [self enhancedStepHueWithParams:params completion:completionHandler];
}
- (void)enhancedMoveToHueAndSaturationWithParams:(MTRColorControlClusterEnhancedMoveToHueAndSaturationParams *)params
                               completionHandler:(MTRStatusCompletion)completionHandler
{
    [self enhancedMoveToHueAndSaturationWithParams:params completion:completionHandler];
}
- (void)colorLoopSetWithParams:(MTRColorControlClusterColorLoopSetParams *)params
             completionHandler:(MTRStatusCompletion)completionHandler
{
    [self colorLoopSetWithParams:params completion:completionHandler];
}
- (void)stopMoveStepWithParams:(MTRColorControlClusterStopMoveStepParams *)params
             completionHandler:(MTRStatusCompletion)completionHandler
{
    [self stopMoveStepWithParams:params completion:completionHandler];
}
- (void)moveColorTemperatureWithParams:(MTRColorControlClusterMoveColorTemperatureParams *)params
                     completionHandler:(MTRStatusCompletion)completionHandler
{
    [self moveColorTemperatureWithParams:params completion:completionHandler];
}
- (void)stepColorTemperatureWithParams:(MTRColorControlClusterStepColorTemperatureParams *)params
                     completionHandler:(MTRStatusCompletion)completionHandler
{
    [self stepColorTemperatureWithParams:params completion:completionHandler];
}

- (void)readAttributeCurrentHueWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentHueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeCurrentHueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeCurrentHueWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeCurrentHueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentHueWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeCurrentSaturationWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentSaturationWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeCurrentSaturationWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeCurrentSaturationWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSNumber *>(value), error);
                                          }];
}
+ (void)readAttributeCurrentSaturationWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentSaturationWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}

- (void)readAttributeRemainingTimeWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRemainingTimeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRemainingTimeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRemainingTimeWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributeRemainingTimeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRemainingTimeWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributeCurrentXWithCompletionHandler:(void (^)(
                                                       NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentXWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeCurrentXWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeCurrentXWithParams:subscribeParams
                       subscriptionEstablished:subscriptionEstablishedHandler
                                 reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                     // Cast is safe because subclass does not add any selectors.
                                     reportHandler(static_cast<NSNumber *>(value), error);
                                 }];
}
+ (void)readAttributeCurrentXWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentXWithClusterStateCache:attributeCacheContainer.realContainer
                                            endpoint:endpoint
                                               queue:queue
                                          completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              completionHandler(static_cast<NSNumber *>(value), error);
                                          }];
}

- (void)readAttributeCurrentYWithCompletionHandler:(void (^)(
                                                       NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentYWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeCurrentYWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeCurrentYWithParams:subscribeParams
                       subscriptionEstablished:subscriptionEstablishedHandler
                                 reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                     // Cast is safe because subclass does not add any selectors.
                                     reportHandler(static_cast<NSNumber *>(value), error);
                                 }];
}
+ (void)readAttributeCurrentYWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentYWithClusterStateCache:attributeCacheContainer.realContainer
                                            endpoint:endpoint
                                               queue:queue
                                          completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              completionHandler(static_cast<NSNumber *>(value), error);
                                          }];
}

- (void)readAttributeDriftCompensationWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeDriftCompensationWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeDriftCompensationWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeDriftCompensationWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSNumber *>(value), error);
                                          }];
}
+ (void)readAttributeDriftCompensationWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDriftCompensationWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}

- (void)readAttributeCompensationTextWithCompletionHandler:(void (^)(NSString * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeCompensationTextWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)
    subscribeAttributeCompensationTextWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeCompensationTextWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSString *>(value), error);
                                         }];
}
+ (void)readAttributeCompensationTextWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCompensationTextWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSString *>(value), error);
                                                  }];
}

- (void)readAttributeColorTemperatureMiredsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    [self readAttributeColorTemperatureMiredsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeColorTemperatureMiredsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                                         params:(MTRSubscribeParams * _Nullable)params
                                        subscriptionEstablished:
                                            (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeColorTemperatureMiredsWithParams:subscribeParams
                                     subscriptionEstablished:subscriptionEstablishedHandler
                                               reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   reportHandler(static_cast<NSNumber *>(value), error);
                                               }];
}
+ (void)readAttributeColorTemperatureMiredsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                            completionHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeColorTemperatureMiredsWithClusterStateCache:attributeCacheContainer.realContainer
                                                          endpoint:endpoint
                                                             queue:queue
                                                        completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                            // Cast is safe because subclass does not add any selectors.
                                                            completionHandler(static_cast<NSNumber *>(value), error);
                                                        }];
}

- (void)readAttributeColorModeWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeColorModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeColorModeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeColorModeWithParams:subscribeParams
                        subscriptionEstablished:subscriptionEstablishedHandler
                                  reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                      // Cast is safe because subclass does not add any selectors.
                                      reportHandler(static_cast<NSNumber *>(value), error);
                                  }];
}
+ (void)readAttributeColorModeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeColorModeWithClusterStateCache:attributeCacheContainer.realContainer
                                             endpoint:endpoint
                                                queue:queue
                                           completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               completionHandler(static_cast<NSNumber *>(value), error);
                                           }];
}

- (void)readAttributeOptionsWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOptionsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeOptionsWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeOptionsWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeOptionsWithValue:(NSNumber * _Nonnull)value
                                params:(MTRWriteParams * _Nullable)params
                     completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeOptionsWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeOptionsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                          params:(MTRSubscribeParams * _Nullable)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeOptionsWithParams:subscribeParams
                      subscriptionEstablished:subscriptionEstablishedHandler
                                reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                    // Cast is safe because subclass does not add any selectors.
                                    reportHandler(static_cast<NSNumber *>(value), error);
                                }];
}
+ (void)readAttributeOptionsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                      endpoint:(NSNumber *)endpoint
                                         queue:(dispatch_queue_t)queue
                             completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOptionsWithClusterStateCache:attributeCacheContainer.realContainer
                                           endpoint:endpoint
                                              queue:queue
                                         completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             completionHandler(static_cast<NSNumber *>(value), error);
                                         }];
}

- (void)readAttributeNumberOfPrimariesWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeNumberOfPrimariesWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeNumberOfPrimariesWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNumberOfPrimariesWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSNumber *>(value), error);
                                          }];
}
+ (void)readAttributeNumberOfPrimariesWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNumberOfPrimariesWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}

- (void)readAttributePrimary1XWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePrimary1XWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributePrimary1XWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePrimary1XWithParams:subscribeParams
                        subscriptionEstablished:subscriptionEstablishedHandler
                                  reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                      // Cast is safe because subclass does not add any selectors.
                                      reportHandler(static_cast<NSNumber *>(value), error);
                                  }];
}
+ (void)readAttributePrimary1XWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePrimary1XWithClusterStateCache:attributeCacheContainer.realContainer
                                             endpoint:endpoint
                                                queue:queue
                                           completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               completionHandler(static_cast<NSNumber *>(value), error);
                                           }];
}

- (void)readAttributePrimary1YWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePrimary1YWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributePrimary1YWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePrimary1YWithParams:subscribeParams
                        subscriptionEstablished:subscriptionEstablishedHandler
                                  reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                      // Cast is safe because subclass does not add any selectors.
                                      reportHandler(static_cast<NSNumber *>(value), error);
                                  }];
}
+ (void)readAttributePrimary1YWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePrimary1YWithClusterStateCache:attributeCacheContainer.realContainer
                                             endpoint:endpoint
                                                queue:queue
                                           completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               completionHandler(static_cast<NSNumber *>(value), error);
                                           }];
}

- (void)readAttributePrimary1IntensityWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributePrimary1IntensityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributePrimary1IntensityWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePrimary1IntensityWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSNumber *>(value), error);
                                          }];
}
+ (void)readAttributePrimary1IntensityWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePrimary1IntensityWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}

- (void)readAttributePrimary2XWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePrimary2XWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributePrimary2XWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePrimary2XWithParams:subscribeParams
                        subscriptionEstablished:subscriptionEstablishedHandler
                                  reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                      // Cast is safe because subclass does not add any selectors.
                                      reportHandler(static_cast<NSNumber *>(value), error);
                                  }];
}
+ (void)readAttributePrimary2XWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePrimary2XWithClusterStateCache:attributeCacheContainer.realContainer
                                             endpoint:endpoint
                                                queue:queue
                                           completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               completionHandler(static_cast<NSNumber *>(value), error);
                                           }];
}

- (void)readAttributePrimary2YWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePrimary2YWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributePrimary2YWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePrimary2YWithParams:subscribeParams
                        subscriptionEstablished:subscriptionEstablishedHandler
                                  reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                      // Cast is safe because subclass does not add any selectors.
                                      reportHandler(static_cast<NSNumber *>(value), error);
                                  }];
}
+ (void)readAttributePrimary2YWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePrimary2YWithClusterStateCache:attributeCacheContainer.realContainer
                                             endpoint:endpoint
                                                queue:queue
                                           completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               completionHandler(static_cast<NSNumber *>(value), error);
                                           }];
}

- (void)readAttributePrimary2IntensityWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributePrimary2IntensityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributePrimary2IntensityWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePrimary2IntensityWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSNumber *>(value), error);
                                          }];
}
+ (void)readAttributePrimary2IntensityWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePrimary2IntensityWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}

- (void)readAttributePrimary3XWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePrimary3XWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributePrimary3XWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePrimary3XWithParams:subscribeParams
                        subscriptionEstablished:subscriptionEstablishedHandler
                                  reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                      // Cast is safe because subclass does not add any selectors.
                                      reportHandler(static_cast<NSNumber *>(value), error);
                                  }];
}
+ (void)readAttributePrimary3XWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePrimary3XWithClusterStateCache:attributeCacheContainer.realContainer
                                             endpoint:endpoint
                                                queue:queue
                                           completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               completionHandler(static_cast<NSNumber *>(value), error);
                                           }];
}

- (void)readAttributePrimary3YWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePrimary3YWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributePrimary3YWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePrimary3YWithParams:subscribeParams
                        subscriptionEstablished:subscriptionEstablishedHandler
                                  reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                      // Cast is safe because subclass does not add any selectors.
                                      reportHandler(static_cast<NSNumber *>(value), error);
                                  }];
}
+ (void)readAttributePrimary3YWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePrimary3YWithClusterStateCache:attributeCacheContainer.realContainer
                                             endpoint:endpoint
                                                queue:queue
                                           completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               completionHandler(static_cast<NSNumber *>(value), error);
                                           }];
}

- (void)readAttributePrimary3IntensityWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributePrimary3IntensityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributePrimary3IntensityWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePrimary3IntensityWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSNumber *>(value), error);
                                          }];
}
+ (void)readAttributePrimary3IntensityWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePrimary3IntensityWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}

- (void)readAttributePrimary4XWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePrimary4XWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributePrimary4XWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePrimary4XWithParams:subscribeParams
                        subscriptionEstablished:subscriptionEstablishedHandler
                                  reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                      // Cast is safe because subclass does not add any selectors.
                                      reportHandler(static_cast<NSNumber *>(value), error);
                                  }];
}
+ (void)readAttributePrimary4XWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePrimary4XWithClusterStateCache:attributeCacheContainer.realContainer
                                             endpoint:endpoint
                                                queue:queue
                                           completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               completionHandler(static_cast<NSNumber *>(value), error);
                                           }];
}

- (void)readAttributePrimary4YWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePrimary4YWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributePrimary4YWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePrimary4YWithParams:subscribeParams
                        subscriptionEstablished:subscriptionEstablishedHandler
                                  reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                      // Cast is safe because subclass does not add any selectors.
                                      reportHandler(static_cast<NSNumber *>(value), error);
                                  }];
}
+ (void)readAttributePrimary4YWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePrimary4YWithClusterStateCache:attributeCacheContainer.realContainer
                                             endpoint:endpoint
                                                queue:queue
                                           completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               completionHandler(static_cast<NSNumber *>(value), error);
                                           }];
}

- (void)readAttributePrimary4IntensityWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributePrimary4IntensityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributePrimary4IntensityWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePrimary4IntensityWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSNumber *>(value), error);
                                          }];
}
+ (void)readAttributePrimary4IntensityWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePrimary4IntensityWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}

- (void)readAttributePrimary5XWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePrimary5XWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributePrimary5XWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePrimary5XWithParams:subscribeParams
                        subscriptionEstablished:subscriptionEstablishedHandler
                                  reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                      // Cast is safe because subclass does not add any selectors.
                                      reportHandler(static_cast<NSNumber *>(value), error);
                                  }];
}
+ (void)readAttributePrimary5XWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePrimary5XWithClusterStateCache:attributeCacheContainer.realContainer
                                             endpoint:endpoint
                                                queue:queue
                                           completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               completionHandler(static_cast<NSNumber *>(value), error);
                                           }];
}

- (void)readAttributePrimary5YWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePrimary5YWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributePrimary5YWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePrimary5YWithParams:subscribeParams
                        subscriptionEstablished:subscriptionEstablishedHandler
                                  reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                      // Cast is safe because subclass does not add any selectors.
                                      reportHandler(static_cast<NSNumber *>(value), error);
                                  }];
}
+ (void)readAttributePrimary5YWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePrimary5YWithClusterStateCache:attributeCacheContainer.realContainer
                                             endpoint:endpoint
                                                queue:queue
                                           completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               completionHandler(static_cast<NSNumber *>(value), error);
                                           }];
}

- (void)readAttributePrimary5IntensityWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributePrimary5IntensityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributePrimary5IntensityWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePrimary5IntensityWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSNumber *>(value), error);
                                          }];
}
+ (void)readAttributePrimary5IntensityWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePrimary5IntensityWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}

- (void)readAttributePrimary6XWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePrimary6XWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributePrimary6XWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePrimary6XWithParams:subscribeParams
                        subscriptionEstablished:subscriptionEstablishedHandler
                                  reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                      // Cast is safe because subclass does not add any selectors.
                                      reportHandler(static_cast<NSNumber *>(value), error);
                                  }];
}
+ (void)readAttributePrimary6XWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePrimary6XWithClusterStateCache:attributeCacheContainer.realContainer
                                             endpoint:endpoint
                                                queue:queue
                                           completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               completionHandler(static_cast<NSNumber *>(value), error);
                                           }];
}

- (void)readAttributePrimary6YWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePrimary6YWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributePrimary6YWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePrimary6YWithParams:subscribeParams
                        subscriptionEstablished:subscriptionEstablishedHandler
                                  reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                      // Cast is safe because subclass does not add any selectors.
                                      reportHandler(static_cast<NSNumber *>(value), error);
                                  }];
}
+ (void)readAttributePrimary6YWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePrimary6YWithClusterStateCache:attributeCacheContainer.realContainer
                                             endpoint:endpoint
                                                queue:queue
                                           completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               completionHandler(static_cast<NSNumber *>(value), error);
                                           }];
}

- (void)readAttributePrimary6IntensityWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributePrimary6IntensityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributePrimary6IntensityWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePrimary6IntensityWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSNumber *>(value), error);
                                          }];
}
+ (void)readAttributePrimary6IntensityWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePrimary6IntensityWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}

- (void)readAttributeWhitePointXWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeWhitePointXWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeWhitePointXWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeWhitePointXWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeWhitePointXWithValue:(NSNumber * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                         completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeWhitePointXWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeWhitePointXWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeWhitePointXWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSNumber *>(value), error);
                                    }];
}
+ (void)readAttributeWhitePointXWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeWhitePointXWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                             }];
}

- (void)readAttributeWhitePointYWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeWhitePointYWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeWhitePointYWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeWhitePointYWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeWhitePointYWithValue:(NSNumber * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                         completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeWhitePointYWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeWhitePointYWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeWhitePointYWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSNumber *>(value), error);
                                    }];
}
+ (void)readAttributeWhitePointYWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeWhitePointYWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                             }];
}

- (void)readAttributeColorPointRXWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeColorPointRXWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeColorPointRXWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeColorPointRXWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeColorPointRXWithValue:(NSNumber * _Nonnull)value
                                     params:(MTRWriteParams * _Nullable)params
                          completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeColorPointRXWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeColorPointRXWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeColorPointRXWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributeColorPointRXWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeColorPointRXWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributeColorPointRYWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeColorPointRYWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeColorPointRYWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeColorPointRYWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeColorPointRYWithValue:(NSNumber * _Nonnull)value
                                     params:(MTRWriteParams * _Nullable)params
                          completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeColorPointRYWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeColorPointRYWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeColorPointRYWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributeColorPointRYWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeColorPointRYWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributeColorPointRIntensityWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeColorPointRIntensityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeColorPointRIntensityWithValue:(NSNumber * _Nullable)value
                                  completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeColorPointRIntensityWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeColorPointRIntensityWithValue:(NSNumber * _Nullable)value
                                             params:(MTRWriteParams * _Nullable)params
                                  completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeColorPointRIntensityWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeColorPointRIntensityWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeColorPointRIntensityWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSNumber *>(value), error);
                                             }];
}
+ (void)readAttributeColorPointRIntensityWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeColorPointRIntensityWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSNumber *>(value), error);
                                                      }];
}

- (void)readAttributeColorPointGXWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeColorPointGXWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeColorPointGXWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeColorPointGXWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeColorPointGXWithValue:(NSNumber * _Nonnull)value
                                     params:(MTRWriteParams * _Nullable)params
                          completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeColorPointGXWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeColorPointGXWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeColorPointGXWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributeColorPointGXWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeColorPointGXWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributeColorPointGYWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeColorPointGYWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeColorPointGYWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeColorPointGYWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeColorPointGYWithValue:(NSNumber * _Nonnull)value
                                     params:(MTRWriteParams * _Nullable)params
                          completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeColorPointGYWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeColorPointGYWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeColorPointGYWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributeColorPointGYWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeColorPointGYWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributeColorPointGIntensityWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeColorPointGIntensityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeColorPointGIntensityWithValue:(NSNumber * _Nullable)value
                                  completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeColorPointGIntensityWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeColorPointGIntensityWithValue:(NSNumber * _Nullable)value
                                             params:(MTRWriteParams * _Nullable)params
                                  completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeColorPointGIntensityWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeColorPointGIntensityWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeColorPointGIntensityWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSNumber *>(value), error);
                                             }];
}
+ (void)readAttributeColorPointGIntensityWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeColorPointGIntensityWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSNumber *>(value), error);
                                                      }];
}

- (void)readAttributeColorPointBXWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeColorPointBXWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeColorPointBXWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeColorPointBXWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeColorPointBXWithValue:(NSNumber * _Nonnull)value
                                     params:(MTRWriteParams * _Nullable)params
                          completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeColorPointBXWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeColorPointBXWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeColorPointBXWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributeColorPointBXWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeColorPointBXWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributeColorPointBYWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeColorPointBYWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeColorPointBYWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeColorPointBYWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeColorPointBYWithValue:(NSNumber * _Nonnull)value
                                     params:(MTRWriteParams * _Nullable)params
                          completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeColorPointBYWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeColorPointBYWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeColorPointBYWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributeColorPointBYWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeColorPointBYWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributeColorPointBIntensityWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeColorPointBIntensityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeColorPointBIntensityWithValue:(NSNumber * _Nullable)value
                                  completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeColorPointBIntensityWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeColorPointBIntensityWithValue:(NSNumber * _Nullable)value
                                             params:(MTRWriteParams * _Nullable)params
                                  completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeColorPointBIntensityWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeColorPointBIntensityWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeColorPointBIntensityWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSNumber *>(value), error);
                                             }];
}
+ (void)readAttributeColorPointBIntensityWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeColorPointBIntensityWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSNumber *>(value), error);
                                                      }];
}

- (void)readAttributeEnhancedCurrentHueWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    [self readAttributeEnhancedCurrentHueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeEnhancedCurrentHueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:
                                        (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeEnhancedCurrentHueWithParams:subscribeParams
                                 subscriptionEstablished:subscriptionEstablishedHandler
                                           reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               reportHandler(static_cast<NSNumber *>(value), error);
                                           }];
}
+ (void)readAttributeEnhancedCurrentHueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeEnhancedCurrentHueWithClusterStateCache:attributeCacheContainer.realContainer
                                                      endpoint:endpoint
                                                         queue:queue
                                                    completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                        // Cast is safe because subclass does not add any selectors.
                                                        completionHandler(static_cast<NSNumber *>(value), error);
                                                    }];
}

- (void)readAttributeEnhancedColorModeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeEnhancedColorModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeEnhancedColorModeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeEnhancedColorModeWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSNumber *>(value), error);
                                          }];
}
+ (void)readAttributeEnhancedColorModeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeEnhancedColorModeWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}

- (void)readAttributeColorLoopActiveWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeColorLoopActiveWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeColorLoopActiveWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeColorLoopActiveWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeColorLoopActiveWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeColorLoopActiveWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (void)readAttributeColorLoopDirectionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    [self readAttributeColorLoopDirectionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeColorLoopDirectionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:
                                        (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeColorLoopDirectionWithParams:subscribeParams
                                 subscriptionEstablished:subscriptionEstablishedHandler
                                           reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               reportHandler(static_cast<NSNumber *>(value), error);
                                           }];
}
+ (void)readAttributeColorLoopDirectionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeColorLoopDirectionWithClusterStateCache:attributeCacheContainer.realContainer
                                                      endpoint:endpoint
                                                         queue:queue
                                                    completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                        // Cast is safe because subclass does not add any selectors.
                                                        completionHandler(static_cast<NSNumber *>(value), error);
                                                    }];
}

- (void)readAttributeColorLoopTimeWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeColorLoopTimeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeColorLoopTimeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeColorLoopTimeWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributeColorLoopTimeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeColorLoopTimeWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributeColorLoopStartEnhancedHueWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    [self readAttributeColorLoopStartEnhancedHueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeColorLoopStartEnhancedHueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                                            params:(MTRSubscribeParams * _Nullable)params
                                           subscriptionEstablished:
                                               (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                     reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeColorLoopStartEnhancedHueWithParams:subscribeParams
                                        subscriptionEstablished:subscriptionEstablishedHandler
                                                  reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      reportHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}
+ (void)readAttributeColorLoopStartEnhancedHueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                               completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    [self readAttributeColorLoopStartEnhancedHueWithClusterStateCache:attributeCacheContainer.realContainer
                                                             endpoint:endpoint
                                                                queue:queue
                                                           completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                               // Cast is safe because subclass does not add any selectors.
                                                               completionHandler(static_cast<NSNumber *>(value), error);
                                                           }];
}

- (void)readAttributeColorLoopStoredEnhancedHueWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    [self readAttributeColorLoopStoredEnhancedHueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeColorLoopStoredEnhancedHueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                                             params:(MTRSubscribeParams * _Nullable)params
                                            subscriptionEstablished:
                                                (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                      reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeColorLoopStoredEnhancedHueWithParams:subscribeParams
                                         subscriptionEstablished:subscriptionEstablishedHandler
                                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       reportHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}
+ (void)readAttributeColorLoopStoredEnhancedHueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                         endpoint:(NSNumber *)endpoint
                                                            queue:(dispatch_queue_t)queue
                                                completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    [self readAttributeColorLoopStoredEnhancedHueWithClusterStateCache:attributeCacheContainer.realContainer
                                                              endpoint:endpoint
                                                                 queue:queue
                                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                // Cast is safe because subclass does not add any selectors.
                                                                completionHandler(static_cast<NSNumber *>(value), error);
                                                            }];
}

- (void)readAttributeColorCapabilitiesWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeColorCapabilitiesWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeColorCapabilitiesWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeColorCapabilitiesWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSNumber *>(value), error);
                                          }];
}
+ (void)readAttributeColorCapabilitiesWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeColorCapabilitiesWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}

- (void)readAttributeColorTempPhysicalMinMiredsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    [self readAttributeColorTempPhysicalMinMiredsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeColorTempPhysicalMinMiredsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                                             params:(MTRSubscribeParams * _Nullable)params
                                            subscriptionEstablished:
                                                (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                      reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeColorTempPhysicalMinMiredsWithParams:subscribeParams
                                         subscriptionEstablished:subscriptionEstablishedHandler
                                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       reportHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}
+ (void)readAttributeColorTempPhysicalMinMiredsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                         endpoint:(NSNumber *)endpoint
                                                            queue:(dispatch_queue_t)queue
                                                completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    [self readAttributeColorTempPhysicalMinMiredsWithClusterStateCache:attributeCacheContainer.realContainer
                                                              endpoint:endpoint
                                                                 queue:queue
                                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                // Cast is safe because subclass does not add any selectors.
                                                                completionHandler(static_cast<NSNumber *>(value), error);
                                                            }];
}

- (void)readAttributeColorTempPhysicalMaxMiredsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    [self readAttributeColorTempPhysicalMaxMiredsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeColorTempPhysicalMaxMiredsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                                             params:(MTRSubscribeParams * _Nullable)params
                                            subscriptionEstablished:
                                                (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                      reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeColorTempPhysicalMaxMiredsWithParams:subscribeParams
                                         subscriptionEstablished:subscriptionEstablishedHandler
                                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       reportHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}
+ (void)readAttributeColorTempPhysicalMaxMiredsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                         endpoint:(NSNumber *)endpoint
                                                            queue:(dispatch_queue_t)queue
                                                completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    [self readAttributeColorTempPhysicalMaxMiredsWithClusterStateCache:attributeCacheContainer.realContainer
                                                              endpoint:endpoint
                                                                 queue:queue
                                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                // Cast is safe because subclass does not add any selectors.
                                                                completionHandler(static_cast<NSNumber *>(value), error);
                                                            }];
}

- (void)readAttributeCoupleColorTempToLevelMinMiredsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeCoupleColorTempToLevelMinMiredsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeCoupleColorTempToLevelMinMiredsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                  params:(MTRSubscribeParams * _Nullable)params
                                                 subscriptionEstablished:
                                                     (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                           reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                             NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeCoupleColorTempToLevelMinMiredsWithParams:subscribeParams
                                              subscriptionEstablished:subscriptionEstablishedHandler
                                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                            // Cast is safe because subclass does not add any selectors.
                                                            reportHandler(static_cast<NSNumber *>(value), error);
                                                        }];
}
+ (void)readAttributeCoupleColorTempToLevelMinMiredsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                              endpoint:(NSNumber *)endpoint
                                                                 queue:(dispatch_queue_t)queue
                                                     completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completionHandler
{
    [self
        readAttributeCoupleColorTempToLevelMinMiredsWithClusterStateCache:attributeCacheContainer.realContainer
                                                                 endpoint:endpoint
                                                                    queue:queue
                                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                   // Cast is safe because subclass does not add any selectors.
                                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                                               }];
}

- (void)readAttributeStartUpColorTemperatureMiredsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))completionHandler
{
    [self readAttributeStartUpColorTemperatureMiredsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeStartUpColorTemperatureMiredsWithValue:(NSNumber * _Nullable)value
                                           completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeStartUpColorTemperatureMiredsWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeStartUpColorTemperatureMiredsWithValue:(NSNumber * _Nullable)value
                                                      params:(MTRWriteParams * _Nullable)params
                                           completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeStartUpColorTemperatureMiredsWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeStartUpColorTemperatureMiredsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                params:(MTRSubscribeParams * _Nullable)params
                                               subscriptionEstablished:
                                                   (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                         reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeStartUpColorTemperatureMiredsWithParams:subscribeParams
                                            subscriptionEstablished:subscriptionEstablishedHandler
                                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          reportHandler(static_cast<NSNumber *>(value), error);
                                                      }];
}
+ (void)readAttributeStartUpColorTemperatureMiredsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                            endpoint:(NSNumber *)endpoint
                                                               queue:(dispatch_queue_t)queue
                                                   completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    [self readAttributeStartUpColorTemperatureMiredsWithClusterStateCache:attributeCacheContainer.realContainer
                                                                 endpoint:endpoint
                                                                    queue:queue
                                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                   // Cast is safe because subclass does not add any selectors.
                                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                                               }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterBallastConfiguration

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)readAttributePhysicalMinLevelWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BallastConfiguration::Attributes::PhysicalMinLevel::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePhysicalMinLevelWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BallastConfiguration::Attributes::PhysicalMinLevel::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePhysicalMinLevelWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BallastConfiguration::Attributes::PhysicalMinLevel::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePhysicalMaxLevelWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BallastConfiguration::Attributes::PhysicalMaxLevel::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePhysicalMaxLevelWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BallastConfiguration::Attributes::PhysicalMaxLevel::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePhysicalMaxLevelWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BallastConfiguration::Attributes::PhysicalMaxLevel::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBallastStatusWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BallastConfiguration::Attributes::BallastStatus::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeBallastStatusWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BallastConfiguration::Attributes::BallastStatus::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeBallastStatusWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BallastConfiguration::Attributes::BallastStatus::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMinLevelWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BallastConfiguration::Attributes::MinLevel::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeMinLevelWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeMinLevelWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeMinLevelWithValue:(NSNumber * _Nonnull)value
                                 params:(MTRWriteParams * _Nullable)params
                             completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BallastConfiguration::Attributes::MinLevel::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeMinLevelWithParams:(MTRSubscribeParams * _Nonnull)params
                     subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                               reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BallastConfiguration::Attributes::MinLevel::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMinLevelWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                        completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BallastConfiguration::Attributes::MinLevel::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMaxLevelWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BallastConfiguration::Attributes::MaxLevel::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeMaxLevelWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeMaxLevelWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeMaxLevelWithValue:(NSNumber * _Nonnull)value
                                 params:(MTRWriteParams * _Nullable)params
                             completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BallastConfiguration::Attributes::MaxLevel::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeMaxLevelWithParams:(MTRSubscribeParams * _Nonnull)params
                     subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                               reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BallastConfiguration::Attributes::MaxLevel::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMaxLevelWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                        completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BallastConfiguration::Attributes::MaxLevel::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeIntrinsicBallastFactorWithCompletion:(void (^)(
                                                              NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BallastConfiguration::Attributes::IntrinsicBallastFactor::TypeInfo;
    return MTRReadAttribute<MTRNullableInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeIntrinsicBallastFactorWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeIntrinsicBallastFactorWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeIntrinsicBallastFactorWithValue:(NSNumber * _Nullable)value
                                               params:(MTRWriteParams * _Nullable)params
                                           completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BallastConfiguration::Attributes::IntrinsicBallastFactor::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedCharValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeIntrinsicBallastFactorWithParams:(MTRSubscribeParams * _Nonnull)params
                                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BallastConfiguration::Attributes::IntrinsicBallastFactor::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeIntrinsicBallastFactorWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                                      completion:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BallastConfiguration::Attributes::IntrinsicBallastFactor::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBallastFactorAdjustmentWithCompletion:(void (^)(
                                                               NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BallastConfiguration::Attributes::BallastFactorAdjustment::TypeInfo;
    return MTRReadAttribute<MTRNullableInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeBallastFactorAdjustmentWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeBallastFactorAdjustmentWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeBallastFactorAdjustmentWithValue:(NSNumber * _Nullable)value
                                                params:(MTRWriteParams * _Nullable)params
                                            completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BallastConfiguration::Attributes::BallastFactorAdjustment::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedCharValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeBallastFactorAdjustmentWithParams:(MTRSubscribeParams * _Nonnull)params
                                    subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BallastConfiguration::Attributes::BallastFactorAdjustment::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeBallastFactorAdjustmentWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                         endpoint:(NSNumber *)endpoint
                                                            queue:(dispatch_queue_t)queue
                                                       completion:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BallastConfiguration::Attributes::BallastFactorAdjustment::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeLampQuantityWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BallastConfiguration::Attributes::LampQuantity::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeLampQuantityWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BallastConfiguration::Attributes::LampQuantity::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeLampQuantityWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BallastConfiguration::Attributes::LampQuantity::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeLampTypeWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BallastConfiguration::Attributes::LampType::TypeInfo;
    return MTRReadAttribute<MTRCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeLampTypeWithValue:(NSString * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeLampTypeWithValue:(NSString * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeLampTypeWithValue:(NSString * _Nonnull)value
                                 params:(MTRWriteParams * _Nullable)params
                             completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BallastConfiguration::Attributes::LampType::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = [self asCharSpan:value];

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeLampTypeWithParams:(MTRSubscribeParams * _Nonnull)params
                     subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                               reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BallastConfiguration::Attributes::LampType::TypeInfo;
    MTRSubscribeAttribute<MTRCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeLampTypeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                        completion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(CharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BallastConfiguration::Attributes::LampType::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeLampManufacturerWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BallastConfiguration::Attributes::LampManufacturer::TypeInfo;
    return MTRReadAttribute<MTRCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeLampManufacturerWithValue:(NSString * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeLampManufacturerWithValue:(NSString * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeLampManufacturerWithValue:(NSString * _Nonnull)value
                                         params:(MTRWriteParams * _Nullable)params
                                     completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BallastConfiguration::Attributes::LampManufacturer::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = [self asCharSpan:value];

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeLampManufacturerWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BallastConfiguration::Attributes::LampManufacturer::TypeInfo;
    MTRSubscribeAttribute<MTRCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeLampManufacturerWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(CharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BallastConfiguration::Attributes::LampManufacturer::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeLampRatedHoursWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BallastConfiguration::Attributes::LampRatedHours::TypeInfo;
    return MTRReadAttribute<MTRNullableInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeLampRatedHoursWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeLampRatedHoursWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeLampRatedHoursWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                                   completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BallastConfiguration::Attributes::LampRatedHours::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedIntValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeLampRatedHoursWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BallastConfiguration::Attributes::LampRatedHours::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeLampRatedHoursWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BallastConfiguration::Attributes::LampRatedHours::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeLampBurnHoursWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BallastConfiguration::Attributes::LampBurnHours::TypeInfo;
    return MTRReadAttribute<MTRNullableInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeLampBurnHoursWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeLampBurnHoursWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeLampBurnHoursWithValue:(NSNumber * _Nullable)value
                                      params:(MTRWriteParams * _Nullable)params
                                  completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BallastConfiguration::Attributes::LampBurnHours::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedIntValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeLampBurnHoursWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BallastConfiguration::Attributes::LampBurnHours::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeLampBurnHoursWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BallastConfiguration::Attributes::LampBurnHours::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeLampAlarmModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BallastConfiguration::Attributes::LampAlarmMode::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeLampAlarmModeWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeLampAlarmModeWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeLampAlarmModeWithValue:(NSNumber * _Nonnull)value
                                      params:(MTRWriteParams * _Nullable)params
                                  completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BallastConfiguration::Attributes::LampAlarmMode::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeLampAlarmModeWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BallastConfiguration::Attributes::LampAlarmMode::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeLampAlarmModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BallastConfiguration::Attributes::LampAlarmMode::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeLampBurnHoursTripPointWithCompletion:(void (^)(
                                                              NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BallastConfiguration::Attributes::LampBurnHoursTripPoint::TypeInfo;
    return MTRReadAttribute<MTRNullableInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeLampBurnHoursTripPointWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeLampBurnHoursTripPointWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeLampBurnHoursTripPointWithValue:(NSNumber * _Nullable)value
                                               params:(MTRWriteParams * _Nullable)params
                                           completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BallastConfiguration::Attributes::LampBurnHoursTripPoint::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedIntValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeLampBurnHoursTripPointWithParams:(MTRSubscribeParams * _Nonnull)params
                                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BallastConfiguration::Attributes::LampBurnHoursTripPoint::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeLampBurnHoursTripPointWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                                      completion:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BallastConfiguration::Attributes::LampBurnHoursTripPoint::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BallastConfiguration::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRBallastConfigurationGeneratedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BallastConfiguration::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRBallastConfigurationGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBallastConfigurationGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(BallastConfigurationGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BallastConfiguration::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BallastConfiguration::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRBallastConfigurationAcceptedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BallastConfiguration::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRBallastConfigurationAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBallastConfigurationAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(BallastConfigurationAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BallastConfiguration::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BallastConfiguration::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRBallastConfigurationEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BallastConfiguration::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRBallastConfigurationEventListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBallastConfigurationEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(BallastConfigurationEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BallastConfiguration::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BallastConfiguration::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRBallastConfigurationAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BallastConfiguration::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRBallastConfigurationAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBallastConfigurationAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(BallastConfigurationAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BallastConfiguration::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BallastConfiguration::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BallastConfiguration::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BallastConfiguration::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = BallastConfiguration::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = BallastConfiguration::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BallastConfiguration::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterBallastConfiguration (Deprecated)

- (void)readAttributePhysicalMinLevelWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributePhysicalMinLevelWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)
    subscribeAttributePhysicalMinLevelWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePhysicalMinLevelWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributePhysicalMinLevelWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePhysicalMinLevelWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributePhysicalMaxLevelWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributePhysicalMaxLevelWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)
    subscribeAttributePhysicalMaxLevelWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePhysicalMaxLevelWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributePhysicalMaxLevelWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePhysicalMaxLevelWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeBallastStatusWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBallastStatusWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeBallastStatusWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeBallastStatusWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributeBallastStatusWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBallastStatusWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributeMinLevelWithCompletionHandler:(void (^)(
                                                       NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMinLevelWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeMinLevelWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeMinLevelWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeMinLevelWithValue:(NSNumber * _Nonnull)value
                                 params:(MTRWriteParams * _Nullable)params
                      completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeMinLevelWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeMinLevelWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMinLevelWithParams:subscribeParams
                       subscriptionEstablished:subscriptionEstablishedHandler
                                 reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                     // Cast is safe because subclass does not add any selectors.
                                     reportHandler(static_cast<NSNumber *>(value), error);
                                 }];
}
+ (void)readAttributeMinLevelWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMinLevelWithClusterStateCache:attributeCacheContainer.realContainer
                                            endpoint:endpoint
                                               queue:queue
                                          completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              completionHandler(static_cast<NSNumber *>(value), error);
                                          }];
}

- (void)readAttributeMaxLevelWithCompletionHandler:(void (^)(
                                                       NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxLevelWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeMaxLevelWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeMaxLevelWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeMaxLevelWithValue:(NSNumber * _Nonnull)value
                                 params:(MTRWriteParams * _Nullable)params
                      completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeMaxLevelWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeMaxLevelWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMaxLevelWithParams:subscribeParams
                       subscriptionEstablished:subscriptionEstablishedHandler
                                 reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                     // Cast is safe because subclass does not add any selectors.
                                     reportHandler(static_cast<NSNumber *>(value), error);
                                 }];
}
+ (void)readAttributeMaxLevelWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxLevelWithClusterStateCache:attributeCacheContainer.realContainer
                                            endpoint:endpoint
                                               queue:queue
                                          completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              completionHandler(static_cast<NSNumber *>(value), error);
                                          }];
}

- (void)readAttributeIntrinsicBalanceFactorWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    [self readAttributeIntrinsicBallastFactorWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeIntrinsicBalanceFactorWithValue:(NSNumber * _Nullable)value
                                    completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeIntrinsicBallastFactorWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeIntrinsicBalanceFactorWithValue:(NSNumber * _Nullable)value
                                               params:(MTRWriteParams * _Nullable)params
                                    completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeIntrinsicBallastFactorWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeIntrinsicBalanceFactorWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                                         params:(MTRSubscribeParams * _Nullable)params
                                        subscriptionEstablished:
                                            (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeIntrinsicBallastFactorWithParams:subscribeParams
                                     subscriptionEstablished:subscriptionEstablishedHandler
                                               reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   reportHandler(static_cast<NSNumber *>(value), error);
                                               }];
}
+ (void)readAttributeIntrinsicBalanceFactorWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                            completionHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeIntrinsicBallastFactorWithClusterStateCache:attributeCacheContainer.realContainer
                                                          endpoint:endpoint
                                                             queue:queue
                                                        completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                            // Cast is safe because subclass does not add any selectors.
                                                            completionHandler(static_cast<NSNumber *>(value), error);
                                                        }];
}

- (void)readAttributeBallastFactorAdjustmentWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    [self readAttributeBallastFactorAdjustmentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeBallastFactorAdjustmentWithValue:(NSNumber * _Nullable)value
                                     completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeBallastFactorAdjustmentWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeBallastFactorAdjustmentWithValue:(NSNumber * _Nullable)value
                                                params:(MTRWriteParams * _Nullable)params
                                     completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeBallastFactorAdjustmentWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeBallastFactorAdjustmentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                                          params:(MTRSubscribeParams * _Nullable)params
                                         subscriptionEstablished:
                                             (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                   reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeBallastFactorAdjustmentWithParams:subscribeParams
                                      subscriptionEstablished:subscriptionEstablishedHandler
                                                reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    reportHandler(static_cast<NSNumber *>(value), error);
                                                }];
}
+ (void)readAttributeBallastFactorAdjustmentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                             completionHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBallastFactorAdjustmentWithClusterStateCache:attributeCacheContainer.realContainer
                                                           endpoint:endpoint
                                                              queue:queue
                                                         completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                             // Cast is safe because subclass does not add any selectors.
                                                             completionHandler(static_cast<NSNumber *>(value), error);
                                                         }];
}

- (void)readAttributeLampQuantityWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLampQuantityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeLampQuantityWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeLampQuantityWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributeLampQuantityWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLampQuantityWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributeLampTypeWithCompletionHandler:(void (^)(
                                                       NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLampTypeWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)writeAttributeLampTypeWithValue:(NSString * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeLampTypeWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeLampTypeWithValue:(NSString * _Nonnull)value
                                 params:(MTRWriteParams * _Nullable)params
                      completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeLampTypeWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeLampTypeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeLampTypeWithParams:subscribeParams
                       subscriptionEstablished:subscriptionEstablishedHandler
                                 reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                     // Cast is safe because subclass does not add any selectors.
                                     reportHandler(static_cast<NSString *>(value), error);
                                 }];
}
+ (void)readAttributeLampTypeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLampTypeWithClusterStateCache:attributeCacheContainer.realContainer
                                            endpoint:endpoint
                                               queue:queue
                                          completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              completionHandler(static_cast<NSString *>(value), error);
                                          }];
}

- (void)readAttributeLampManufacturerWithCompletionHandler:(void (^)(NSString * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeLampManufacturerWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)writeAttributeLampManufacturerWithValue:(NSString * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeLampManufacturerWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeLampManufacturerWithValue:(NSString * _Nonnull)value
                                         params:(MTRWriteParams * _Nullable)params
                              completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeLampManufacturerWithValue:value params:params completion:completionHandler];
}
- (void)
    subscribeAttributeLampManufacturerWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeLampManufacturerWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSString *>(value), error);
                                         }];
}
+ (void)readAttributeLampManufacturerWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLampManufacturerWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSString *>(value), error);
                                                  }];
}

- (void)readAttributeLampRatedHoursWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeLampRatedHoursWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeLampRatedHoursWithValue:(NSNumber * _Nullable)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeLampRatedHoursWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeLampRatedHoursWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                            completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeLampRatedHoursWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeLampRatedHoursWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeLampRatedHoursWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSNumber *>(value), error);
                                       }];
}
+ (void)readAttributeLampRatedHoursWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLampRatedHoursWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSNumber *>(value), error);
                                                }];
}

- (void)readAttributeLampBurnHoursWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLampBurnHoursWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeLampBurnHoursWithValue:(NSNumber * _Nullable)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeLampBurnHoursWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeLampBurnHoursWithValue:(NSNumber * _Nullable)value
                                      params:(MTRWriteParams * _Nullable)params
                           completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeLampBurnHoursWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeLampBurnHoursWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeLampBurnHoursWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributeLampBurnHoursWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLampBurnHoursWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributeLampAlarmModeWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLampAlarmModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeLampAlarmModeWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeLampAlarmModeWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeLampAlarmModeWithValue:(NSNumber * _Nonnull)value
                                      params:(MTRWriteParams * _Nullable)params
                           completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeLampAlarmModeWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeLampAlarmModeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeLampAlarmModeWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributeLampAlarmModeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLampAlarmModeWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributeLampBurnHoursTripPointWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    [self readAttributeLampBurnHoursTripPointWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeLampBurnHoursTripPointWithValue:(NSNumber * _Nullable)value
                                    completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeLampBurnHoursTripPointWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeLampBurnHoursTripPointWithValue:(NSNumber * _Nullable)value
                                               params:(MTRWriteParams * _Nullable)params
                                    completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeLampBurnHoursTripPointWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeLampBurnHoursTripPointWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                                         params:(MTRSubscribeParams * _Nullable)params
                                        subscriptionEstablished:
                                            (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeLampBurnHoursTripPointWithParams:subscribeParams
                                     subscriptionEstablished:subscriptionEstablishedHandler
                                               reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   reportHandler(static_cast<NSNumber *>(value), error);
                                               }];
}
+ (void)readAttributeLampBurnHoursTripPointWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                            completionHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLampBurnHoursTripPointWithClusterStateCache:attributeCacheContainer.realContainer
                                                          endpoint:endpoint
                                                             queue:queue
                                                        completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                            // Cast is safe because subclass does not add any selectors.
                                                            completionHandler(static_cast<NSNumber *>(value), error);
                                                        }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterIlluminanceMeasurement

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)readAttributeMeasuredValueWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = IlluminanceMeasurement::Attributes::MeasuredValue::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMeasuredValueWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = IlluminanceMeasurement::Attributes::MeasuredValue::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMeasuredValueWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = IlluminanceMeasurement::Attributes::MeasuredValue::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMinMeasuredValueWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = IlluminanceMeasurement::Attributes::MinMeasuredValue::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMinMeasuredValueWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = IlluminanceMeasurement::Attributes::MinMeasuredValue::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMinMeasuredValueWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = IlluminanceMeasurement::Attributes::MinMeasuredValue::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMaxMeasuredValueWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = IlluminanceMeasurement::Attributes::MaxMeasuredValue::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMaxMeasuredValueWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = IlluminanceMeasurement::Attributes::MaxMeasuredValue::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMaxMeasuredValueWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = IlluminanceMeasurement::Attributes::MaxMeasuredValue::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeToleranceWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = IlluminanceMeasurement::Attributes::Tolerance::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeToleranceWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = IlluminanceMeasurement::Attributes::Tolerance::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeToleranceWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = IlluminanceMeasurement::Attributes::Tolerance::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeLightSensorTypeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = IlluminanceMeasurement::Attributes::LightSensorType::TypeInfo;
    return MTRReadAttribute<MTRNullableInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeLightSensorTypeWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = IlluminanceMeasurement::Attributes::LightSensorType::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeLightSensorTypeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = IlluminanceMeasurement::Attributes::LightSensorType::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = IlluminanceMeasurement::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRIlluminanceMeasurementGeneratedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = IlluminanceMeasurement::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRIlluminanceMeasurementGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRIlluminanceMeasurementGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(IlluminanceMeasurementGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = IlluminanceMeasurement::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = IlluminanceMeasurement::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRIlluminanceMeasurementAcceptedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = IlluminanceMeasurement::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRIlluminanceMeasurementAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRIlluminanceMeasurementAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(IlluminanceMeasurementAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = IlluminanceMeasurement::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = IlluminanceMeasurement::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRIlluminanceMeasurementEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = IlluminanceMeasurement::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRIlluminanceMeasurementEventListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRIlluminanceMeasurementEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(IlluminanceMeasurementEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = IlluminanceMeasurement::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = IlluminanceMeasurement::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRIlluminanceMeasurementAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = IlluminanceMeasurement::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRIlluminanceMeasurementAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRIlluminanceMeasurementAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(IlluminanceMeasurementAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = IlluminanceMeasurement::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = IlluminanceMeasurement::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = IlluminanceMeasurement::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = IlluminanceMeasurement::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = IlluminanceMeasurement::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = IlluminanceMeasurement::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = IlluminanceMeasurement::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterIlluminanceMeasurement (Deprecated)

- (void)readAttributeMeasuredValueWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMeasuredValueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeMeasuredValueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMeasuredValueWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributeMeasuredValueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMeasuredValueWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributeMinMeasuredValueWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeMinMeasuredValueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)
    subscribeAttributeMinMeasuredValueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMinMeasuredValueWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributeMinMeasuredValueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMinMeasuredValueWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeMaxMeasuredValueWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxMeasuredValueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)
    subscribeAttributeMaxMeasuredValueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMaxMeasuredValueWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributeMaxMeasuredValueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxMeasuredValueWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeToleranceWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeToleranceWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeToleranceWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeToleranceWithParams:subscribeParams
                        subscriptionEstablished:subscriptionEstablishedHandler
                                  reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                      // Cast is safe because subclass does not add any selectors.
                                      reportHandler(static_cast<NSNumber *>(value), error);
                                  }];
}
+ (void)readAttributeToleranceWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeToleranceWithClusterStateCache:attributeCacheContainer.realContainer
                                             endpoint:endpoint
                                                queue:queue
                                           completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               completionHandler(static_cast<NSNumber *>(value), error);
                                           }];
}

- (void)readAttributeLightSensorTypeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeLightSensorTypeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeLightSensorTypeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeLightSensorTypeWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeLightSensorTypeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLightSensorTypeWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterTemperatureMeasurement

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)readAttributeMeasuredValueWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TemperatureMeasurement::Attributes::MeasuredValue::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMeasuredValueWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TemperatureMeasurement::Attributes::MeasuredValue::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMeasuredValueWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TemperatureMeasurement::Attributes::MeasuredValue::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMinMeasuredValueWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TemperatureMeasurement::Attributes::MinMeasuredValue::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMinMeasuredValueWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TemperatureMeasurement::Attributes::MinMeasuredValue::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMinMeasuredValueWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TemperatureMeasurement::Attributes::MinMeasuredValue::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMaxMeasuredValueWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TemperatureMeasurement::Attributes::MaxMeasuredValue::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMaxMeasuredValueWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TemperatureMeasurement::Attributes::MaxMeasuredValue::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMaxMeasuredValueWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TemperatureMeasurement::Attributes::MaxMeasuredValue::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeToleranceWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TemperatureMeasurement::Attributes::Tolerance::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeToleranceWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TemperatureMeasurement::Attributes::Tolerance::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeToleranceWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TemperatureMeasurement::Attributes::Tolerance::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TemperatureMeasurement::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRTemperatureMeasurementGeneratedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TemperatureMeasurement::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRTemperatureMeasurementGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRTemperatureMeasurementGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(TemperatureMeasurementGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TemperatureMeasurement::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TemperatureMeasurement::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRTemperatureMeasurementAcceptedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TemperatureMeasurement::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRTemperatureMeasurementAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRTemperatureMeasurementAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(TemperatureMeasurementAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TemperatureMeasurement::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TemperatureMeasurement::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRTemperatureMeasurementEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TemperatureMeasurement::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRTemperatureMeasurementEventListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRTemperatureMeasurementEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(TemperatureMeasurementEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TemperatureMeasurement::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TemperatureMeasurement::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRTemperatureMeasurementAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TemperatureMeasurement::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRTemperatureMeasurementAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRTemperatureMeasurementAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(TemperatureMeasurementAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TemperatureMeasurement::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TemperatureMeasurement::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TemperatureMeasurement::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TemperatureMeasurement::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TemperatureMeasurement::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TemperatureMeasurement::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TemperatureMeasurement::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterTemperatureMeasurement (Deprecated)

- (void)readAttributeMeasuredValueWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMeasuredValueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeMeasuredValueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMeasuredValueWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributeMeasuredValueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMeasuredValueWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributeMinMeasuredValueWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeMinMeasuredValueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)
    subscribeAttributeMinMeasuredValueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMinMeasuredValueWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributeMinMeasuredValueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMinMeasuredValueWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeMaxMeasuredValueWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxMeasuredValueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)
    subscribeAttributeMaxMeasuredValueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMaxMeasuredValueWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributeMaxMeasuredValueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxMeasuredValueWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeToleranceWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeToleranceWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeToleranceWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeToleranceWithParams:subscribeParams
                        subscriptionEstablished:subscriptionEstablishedHandler
                                  reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                      // Cast is safe because subclass does not add any selectors.
                                      reportHandler(static_cast<NSNumber *>(value), error);
                                  }];
}
+ (void)readAttributeToleranceWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeToleranceWithClusterStateCache:attributeCacheContainer.realContainer
                                             endpoint:endpoint
                                                queue:queue
                                           completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               completionHandler(static_cast<NSNumber *>(value), error);
                                           }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterPressureMeasurement

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)readAttributeMeasuredValueWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PressureMeasurement::Attributes::MeasuredValue::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMeasuredValueWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PressureMeasurement::Attributes::MeasuredValue::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMeasuredValueWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PressureMeasurement::Attributes::MeasuredValue::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMinMeasuredValueWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PressureMeasurement::Attributes::MinMeasuredValue::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMinMeasuredValueWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PressureMeasurement::Attributes::MinMeasuredValue::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMinMeasuredValueWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PressureMeasurement::Attributes::MinMeasuredValue::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMaxMeasuredValueWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PressureMeasurement::Attributes::MaxMeasuredValue::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMaxMeasuredValueWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PressureMeasurement::Attributes::MaxMeasuredValue::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMaxMeasuredValueWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PressureMeasurement::Attributes::MaxMeasuredValue::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeToleranceWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PressureMeasurement::Attributes::Tolerance::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeToleranceWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PressureMeasurement::Attributes::Tolerance::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeToleranceWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PressureMeasurement::Attributes::Tolerance::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeScaledValueWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PressureMeasurement::Attributes::ScaledValue::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeScaledValueWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PressureMeasurement::Attributes::ScaledValue::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeScaledValueWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PressureMeasurement::Attributes::ScaledValue::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMinScaledValueWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PressureMeasurement::Attributes::MinScaledValue::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMinScaledValueWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PressureMeasurement::Attributes::MinScaledValue::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMinScaledValueWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PressureMeasurement::Attributes::MinScaledValue::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMaxScaledValueWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PressureMeasurement::Attributes::MaxScaledValue::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMaxScaledValueWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PressureMeasurement::Attributes::MaxScaledValue::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMaxScaledValueWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PressureMeasurement::Attributes::MaxScaledValue::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeScaledToleranceWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PressureMeasurement::Attributes::ScaledTolerance::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeScaledToleranceWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PressureMeasurement::Attributes::ScaledTolerance::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeScaledToleranceWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PressureMeasurement::Attributes::ScaledTolerance::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeScaleWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PressureMeasurement::Attributes::Scale::TypeInfo;
    return MTRReadAttribute<MTRInt8sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeScaleWithParams:(MTRSubscribeParams * _Nonnull)params
                  subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                            reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PressureMeasurement::Attributes::Scale::TypeInfo;
    MTRSubscribeAttribute<MTRInt8sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeScaleWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                                     completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PressureMeasurement::Attributes::Scale::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PressureMeasurement::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRPressureMeasurementGeneratedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PressureMeasurement::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRPressureMeasurementGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRPressureMeasurementGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(PressureMeasurementGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PressureMeasurement::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PressureMeasurement::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRPressureMeasurementAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PressureMeasurement::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRPressureMeasurementAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRPressureMeasurementAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(PressureMeasurementAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PressureMeasurement::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PressureMeasurement::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRPressureMeasurementEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PressureMeasurement::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRPressureMeasurementEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRPressureMeasurementEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(PressureMeasurementEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PressureMeasurement::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PressureMeasurement::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRPressureMeasurementAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PressureMeasurement::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRPressureMeasurementAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRPressureMeasurementAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(PressureMeasurementAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PressureMeasurement::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PressureMeasurement::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PressureMeasurement::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PressureMeasurement::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = PressureMeasurement::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = PressureMeasurement::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PressureMeasurement::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterPressureMeasurement (Deprecated)

- (void)readAttributeMeasuredValueWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMeasuredValueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeMeasuredValueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMeasuredValueWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributeMeasuredValueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMeasuredValueWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributeMinMeasuredValueWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeMinMeasuredValueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)
    subscribeAttributeMinMeasuredValueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMinMeasuredValueWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributeMinMeasuredValueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMinMeasuredValueWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeMaxMeasuredValueWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxMeasuredValueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)
    subscribeAttributeMaxMeasuredValueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMaxMeasuredValueWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributeMaxMeasuredValueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxMeasuredValueWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeToleranceWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeToleranceWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeToleranceWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeToleranceWithParams:subscribeParams
                        subscriptionEstablished:subscriptionEstablishedHandler
                                  reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                      // Cast is safe because subclass does not add any selectors.
                                      reportHandler(static_cast<NSNumber *>(value), error);
                                  }];
}
+ (void)readAttributeToleranceWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeToleranceWithClusterStateCache:attributeCacheContainer.realContainer
                                             endpoint:endpoint
                                                queue:queue
                                           completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               completionHandler(static_cast<NSNumber *>(value), error);
                                           }];
}

- (void)readAttributeScaledValueWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeScaledValueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeScaledValueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeScaledValueWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSNumber *>(value), error);
                                    }];
}
+ (void)readAttributeScaledValueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeScaledValueWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                             }];
}

- (void)readAttributeMinScaledValueWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeMinScaledValueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeMinScaledValueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMinScaledValueWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSNumber *>(value), error);
                                       }];
}
+ (void)readAttributeMinScaledValueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMinScaledValueWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSNumber *>(value), error);
                                                }];
}

- (void)readAttributeMaxScaledValueWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxScaledValueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeMaxScaledValueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMaxScaledValueWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSNumber *>(value), error);
                                       }];
}
+ (void)readAttributeMaxScaledValueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxScaledValueWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSNumber *>(value), error);
                                                }];
}

- (void)readAttributeScaledToleranceWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeScaledToleranceWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeScaledToleranceWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeScaledToleranceWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeScaledToleranceWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeScaledToleranceWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (void)readAttributeScaleWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeScaleWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeScaleWithMinInterval:(NSNumber * _Nonnull)minInterval
                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                        params:(MTRSubscribeParams * _Nullable)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeScaleWithParams:subscribeParams
                    subscriptionEstablished:subscriptionEstablishedHandler
                              reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                  // Cast is safe because subclass does not add any selectors.
                                  reportHandler(static_cast<NSNumber *>(value), error);
                              }];
}
+ (void)readAttributeScaleWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                    endpoint:(NSNumber *)endpoint
                                       queue:(dispatch_queue_t)queue
                           completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeScaleWithClusterStateCache:attributeCacheContainer.realContainer
                                         endpoint:endpoint
                                            queue:queue
                                       completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           completionHandler(static_cast<NSNumber *>(value), error);
                                       }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterFlowMeasurement

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)readAttributeMeasuredValueWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FlowMeasurement::Attributes::MeasuredValue::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMeasuredValueWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FlowMeasurement::Attributes::MeasuredValue::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMeasuredValueWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FlowMeasurement::Attributes::MeasuredValue::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMinMeasuredValueWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FlowMeasurement::Attributes::MinMeasuredValue::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMinMeasuredValueWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FlowMeasurement::Attributes::MinMeasuredValue::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMinMeasuredValueWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FlowMeasurement::Attributes::MinMeasuredValue::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMaxMeasuredValueWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FlowMeasurement::Attributes::MaxMeasuredValue::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMaxMeasuredValueWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FlowMeasurement::Attributes::MaxMeasuredValue::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMaxMeasuredValueWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FlowMeasurement::Attributes::MaxMeasuredValue::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeToleranceWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FlowMeasurement::Attributes::Tolerance::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeToleranceWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FlowMeasurement::Attributes::Tolerance::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeToleranceWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FlowMeasurement::Attributes::Tolerance::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FlowMeasurement::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRFlowMeasurementGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FlowMeasurement::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRFlowMeasurementGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRFlowMeasurementGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(FlowMeasurementGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FlowMeasurement::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FlowMeasurement::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRFlowMeasurementAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FlowMeasurement::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRFlowMeasurementAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRFlowMeasurementAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(FlowMeasurementAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FlowMeasurement::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FlowMeasurement::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRFlowMeasurementEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FlowMeasurement::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRFlowMeasurementEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRFlowMeasurementEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(FlowMeasurementEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FlowMeasurement::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FlowMeasurement::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRFlowMeasurementAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FlowMeasurement::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRFlowMeasurementAttributeListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRFlowMeasurementAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(FlowMeasurementAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FlowMeasurement::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FlowMeasurement::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FlowMeasurement::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FlowMeasurement::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = FlowMeasurement::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = FlowMeasurement::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FlowMeasurement::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterFlowMeasurement (Deprecated)

- (void)readAttributeMeasuredValueWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMeasuredValueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeMeasuredValueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMeasuredValueWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributeMeasuredValueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMeasuredValueWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributeMinMeasuredValueWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeMinMeasuredValueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)
    subscribeAttributeMinMeasuredValueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMinMeasuredValueWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributeMinMeasuredValueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMinMeasuredValueWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeMaxMeasuredValueWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxMeasuredValueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)
    subscribeAttributeMaxMeasuredValueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMaxMeasuredValueWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributeMaxMeasuredValueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxMeasuredValueWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeToleranceWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeToleranceWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeToleranceWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeToleranceWithParams:subscribeParams
                        subscriptionEstablished:subscriptionEstablishedHandler
                                  reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                      // Cast is safe because subclass does not add any selectors.
                                      reportHandler(static_cast<NSNumber *>(value), error);
                                  }];
}
+ (void)readAttributeToleranceWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeToleranceWithClusterStateCache:attributeCacheContainer.realContainer
                                             endpoint:endpoint
                                                queue:queue
                                           completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               completionHandler(static_cast<NSNumber *>(value), error);
                                           }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterRelativeHumidityMeasurement

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)readAttributeMeasuredValueWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = RelativeHumidityMeasurement::Attributes::MeasuredValue::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMeasuredValueWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = RelativeHumidityMeasurement::Attributes::MeasuredValue::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMeasuredValueWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = RelativeHumidityMeasurement::Attributes::MeasuredValue::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMinMeasuredValueWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = RelativeHumidityMeasurement::Attributes::MinMeasuredValue::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMinMeasuredValueWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = RelativeHumidityMeasurement::Attributes::MinMeasuredValue::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMinMeasuredValueWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = RelativeHumidityMeasurement::Attributes::MinMeasuredValue::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMaxMeasuredValueWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = RelativeHumidityMeasurement::Attributes::MaxMeasuredValue::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMaxMeasuredValueWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = RelativeHumidityMeasurement::Attributes::MaxMeasuredValue::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMaxMeasuredValueWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = RelativeHumidityMeasurement::Attributes::MaxMeasuredValue::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeToleranceWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = RelativeHumidityMeasurement::Attributes::Tolerance::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeToleranceWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = RelativeHumidityMeasurement::Attributes::Tolerance::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeToleranceWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = RelativeHumidityMeasurement::Attributes::Tolerance::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = RelativeHumidityMeasurement::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRRelativeHumidityMeasurementGeneratedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = RelativeHumidityMeasurement::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRRelativeHumidityMeasurementGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRRelativeHumidityMeasurementGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(RelativeHumidityMeasurementGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = RelativeHumidityMeasurement::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = RelativeHumidityMeasurement::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRRelativeHumidityMeasurementAcceptedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = RelativeHumidityMeasurement::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRRelativeHumidityMeasurementAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRRelativeHumidityMeasurementAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(RelativeHumidityMeasurementAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = RelativeHumidityMeasurement::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = RelativeHumidityMeasurement::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRRelativeHumidityMeasurementEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = RelativeHumidityMeasurement::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRRelativeHumidityMeasurementEventListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRRelativeHumidityMeasurementEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(RelativeHumidityMeasurementEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = RelativeHumidityMeasurement::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = RelativeHumidityMeasurement::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRRelativeHumidityMeasurementAttributeListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = RelativeHumidityMeasurement::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRRelativeHumidityMeasurementAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRRelativeHumidityMeasurementAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(RelativeHumidityMeasurementAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = RelativeHumidityMeasurement::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = RelativeHumidityMeasurement::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = RelativeHumidityMeasurement::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = RelativeHumidityMeasurement::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = RelativeHumidityMeasurement::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = RelativeHumidityMeasurement::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = RelativeHumidityMeasurement::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterRelativeHumidityMeasurement (Deprecated)

- (void)readAttributeMeasuredValueWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMeasuredValueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeMeasuredValueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMeasuredValueWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributeMeasuredValueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMeasuredValueWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributeMinMeasuredValueWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeMinMeasuredValueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)
    subscribeAttributeMinMeasuredValueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMinMeasuredValueWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributeMinMeasuredValueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMinMeasuredValueWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeMaxMeasuredValueWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxMeasuredValueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)
    subscribeAttributeMaxMeasuredValueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMaxMeasuredValueWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributeMaxMeasuredValueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMaxMeasuredValueWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeToleranceWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeToleranceWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeToleranceWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeToleranceWithParams:subscribeParams
                        subscriptionEstablished:subscriptionEstablishedHandler
                                  reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                      // Cast is safe because subclass does not add any selectors.
                                      reportHandler(static_cast<NSNumber *>(value), error);
                                  }];
}
+ (void)readAttributeToleranceWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeToleranceWithClusterStateCache:attributeCacheContainer.realContainer
                                             endpoint:endpoint
                                                queue:queue
                                           completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               completionHandler(static_cast<NSNumber *>(value), error);
                                           }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterOccupancySensing

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)readAttributeOccupancyWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OccupancySensing::Attributes::Occupancy::TypeInfo;
    return MTRReadAttribute<MTROccupancySensingOccupancyAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeOccupancyWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OccupancySensing::Attributes::Occupancy::TypeInfo;
    MTRSubscribeAttribute<MTROccupancySensingOccupancyAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeOccupancyWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTROccupancySensingOccupancyAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(OccupancySensingOccupancyAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OccupancySensing::Attributes::Occupancy::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeOccupancySensorTypeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OccupancySensing::Attributes::OccupancySensorType::TypeInfo;
    return MTRReadAttribute<MTROccupancySensingClusterOccupancySensorTypeEnumAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeOccupancySensorTypeWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OccupancySensing::Attributes::OccupancySensorType::TypeInfo;
    MTRSubscribeAttribute<MTROccupancySensingClusterOccupancySensorTypeEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeOccupancySensorTypeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTROccupancySensingClusterOccupancySensorTypeEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(OccupancySensingClusterOccupancySensorTypeEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OccupancySensing::Attributes::OccupancySensorType::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeOccupancySensorTypeBitmapWithCompletion:(void (^)(
                                                                 NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OccupancySensing::Attributes::OccupancySensorTypeBitmap::TypeInfo;
    return MTRReadAttribute<MTROccupancySensingOccupancySensorTypeBitmapAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeOccupancySensorTypeBitmapWithParams:(MTRSubscribeParams * _Nonnull)params
                                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OccupancySensing::Attributes::OccupancySensorTypeBitmap::TypeInfo;
    MTRSubscribeAttribute<MTROccupancySensingOccupancySensorTypeBitmapAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeOccupancySensorTypeBitmapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                           endpoint:(NSNumber *)endpoint
                                                              queue:(dispatch_queue_t)queue
                                                         completion:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completion
{
    auto * bridge = new MTROccupancySensingOccupancySensorTypeBitmapAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(OccupancySensingOccupancySensorTypeBitmapAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OccupancySensing::Attributes::OccupancySensorTypeBitmap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePIROccupiedToUnoccupiedDelayWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OccupancySensing::Attributes::PIROccupiedToUnoccupiedDelay::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributePIROccupiedToUnoccupiedDelayWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributePIROccupiedToUnoccupiedDelayWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributePIROccupiedToUnoccupiedDelayWithValue:(NSNumber * _Nonnull)value
                                                     params:(MTRWriteParams * _Nullable)params
                                                 completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = OccupancySensing::Attributes::PIROccupiedToUnoccupiedDelay::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributePIROccupiedToUnoccupiedDelayWithParams:(MTRSubscribeParams * _Nonnull)params
                                         subscriptionEstablished:
                                             (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                   reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))reportHandler
{
    using TypeInfo = OccupancySensing::Attributes::PIROccupiedToUnoccupiedDelay::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePIROccupiedToUnoccupiedDelayWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                              endpoint:(NSNumber *)endpoint
                                                                 queue:(dispatch_queue_t)queue
                                                            completion:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OccupancySensing::Attributes::PIROccupiedToUnoccupiedDelay::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePIRUnoccupiedToOccupiedDelayWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OccupancySensing::Attributes::PIRUnoccupiedToOccupiedDelay::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributePIRUnoccupiedToOccupiedDelayWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributePIRUnoccupiedToOccupiedDelayWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributePIRUnoccupiedToOccupiedDelayWithValue:(NSNumber * _Nonnull)value
                                                     params:(MTRWriteParams * _Nullable)params
                                                 completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = OccupancySensing::Attributes::PIRUnoccupiedToOccupiedDelay::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributePIRUnoccupiedToOccupiedDelayWithParams:(MTRSubscribeParams * _Nonnull)params
                                         subscriptionEstablished:
                                             (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                   reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))reportHandler
{
    using TypeInfo = OccupancySensing::Attributes::PIRUnoccupiedToOccupiedDelay::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePIRUnoccupiedToOccupiedDelayWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                              endpoint:(NSNumber *)endpoint
                                                                 queue:(dispatch_queue_t)queue
                                                            completion:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OccupancySensing::Attributes::PIRUnoccupiedToOccupiedDelay::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePIRUnoccupiedToOccupiedThresholdWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OccupancySensing::Attributes::PIRUnoccupiedToOccupiedThreshold::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributePIRUnoccupiedToOccupiedThresholdWithValue:(NSNumber * _Nonnull)value
                                                     completion:(MTRStatusCompletion)completion
{
    [self writeAttributePIRUnoccupiedToOccupiedThresholdWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributePIRUnoccupiedToOccupiedThresholdWithValue:(NSNumber * _Nonnull)value
                                                         params:(MTRWriteParams * _Nullable)params
                                                     completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = OccupancySensing::Attributes::PIRUnoccupiedToOccupiedThreshold::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributePIRUnoccupiedToOccupiedThresholdWithParams:(MTRSubscribeParams * _Nonnull)params
                                             subscriptionEstablished:
                                                 (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                       reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))reportHandler
{
    using TypeInfo = OccupancySensing::Attributes::PIRUnoccupiedToOccupiedThreshold::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePIRUnoccupiedToOccupiedThresholdWithClusterStateCache:
            (MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                                  endpoint:(NSNumber *)endpoint
                                                                     queue:(dispatch_queue_t)queue
                                                                completion:(void (^)(NSNumber * _Nullable value,
                                                                               NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OccupancySensing::Attributes::PIRUnoccupiedToOccupiedThreshold::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeUltrasonicOccupiedToUnoccupiedDelayWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OccupancySensing::Attributes::UltrasonicOccupiedToUnoccupiedDelay::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeUltrasonicOccupiedToUnoccupiedDelayWithValue:(NSNumber * _Nonnull)value
                                                        completion:(MTRStatusCompletion)completion
{
    [self writeAttributeUltrasonicOccupiedToUnoccupiedDelayWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeUltrasonicOccupiedToUnoccupiedDelayWithValue:(NSNumber * _Nonnull)value
                                                            params:(MTRWriteParams * _Nullable)params
                                                        completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = OccupancySensing::Attributes::UltrasonicOccupiedToUnoccupiedDelay::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeUltrasonicOccupiedToUnoccupiedDelayWithParams:(MTRSubscribeParams * _Nonnull)params
                                                subscriptionEstablished:
                                                    (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                          reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))reportHandler
{
    using TypeInfo = OccupancySensing::Attributes::UltrasonicOccupiedToUnoccupiedDelay::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeUltrasonicOccupiedToUnoccupiedDelayWithClusterStateCache:
            (MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                                     endpoint:(NSNumber *)endpoint
                                                                        queue:(dispatch_queue_t)queue
                                                                   completion:(void (^)(NSNumber * _Nullable value,
                                                                                  NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OccupancySensing::Attributes::UltrasonicOccupiedToUnoccupiedDelay::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeUltrasonicUnoccupiedToOccupiedDelayWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OccupancySensing::Attributes::UltrasonicUnoccupiedToOccupiedDelay::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeUltrasonicUnoccupiedToOccupiedDelayWithValue:(NSNumber * _Nonnull)value
                                                        completion:(MTRStatusCompletion)completion
{
    [self writeAttributeUltrasonicUnoccupiedToOccupiedDelayWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeUltrasonicUnoccupiedToOccupiedDelayWithValue:(NSNumber * _Nonnull)value
                                                            params:(MTRWriteParams * _Nullable)params
                                                        completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = OccupancySensing::Attributes::UltrasonicUnoccupiedToOccupiedDelay::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeUltrasonicUnoccupiedToOccupiedDelayWithParams:(MTRSubscribeParams * _Nonnull)params
                                                subscriptionEstablished:
                                                    (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                          reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))reportHandler
{
    using TypeInfo = OccupancySensing::Attributes::UltrasonicUnoccupiedToOccupiedDelay::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeUltrasonicUnoccupiedToOccupiedDelayWithClusterStateCache:
            (MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                                     endpoint:(NSNumber *)endpoint
                                                                        queue:(dispatch_queue_t)queue
                                                                   completion:(void (^)(NSNumber * _Nullable value,
                                                                                  NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OccupancySensing::Attributes::UltrasonicUnoccupiedToOccupiedDelay::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeUltrasonicUnoccupiedToOccupiedThresholdWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                               NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OccupancySensing::Attributes::UltrasonicUnoccupiedToOccupiedThreshold::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeUltrasonicUnoccupiedToOccupiedThresholdWithValue:(NSNumber * _Nonnull)value
                                                            completion:(MTRStatusCompletion)completion
{
    [self writeAttributeUltrasonicUnoccupiedToOccupiedThresholdWithValue:(NSNumber * _Nonnull) value
                                                                  params:nil
                                                              completion:completion];
}
- (void)writeAttributeUltrasonicUnoccupiedToOccupiedThresholdWithValue:(NSNumber * _Nonnull)value
                                                                params:(MTRWriteParams * _Nullable)params
                                                            completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = OccupancySensing::Attributes::UltrasonicUnoccupiedToOccupiedThreshold::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeUltrasonicUnoccupiedToOccupiedThresholdWithParams:(MTRSubscribeParams * _Nonnull)params
                                                    subscriptionEstablished:
                                                        (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                              reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                NSError * _Nullable error))reportHandler
{
    using TypeInfo = OccupancySensing::Attributes::UltrasonicUnoccupiedToOccupiedThreshold::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeUltrasonicUnoccupiedToOccupiedThresholdWithClusterStateCache:
            (MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                                         endpoint:(NSNumber *)endpoint
                                                                            queue:(dispatch_queue_t)queue
                                                                       completion:(void (^)(NSNumber * _Nullable value,
                                                                                      NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OccupancySensing::Attributes::UltrasonicUnoccupiedToOccupiedThreshold::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePhysicalContactOccupiedToUnoccupiedDelayWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                                NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OccupancySensing::Attributes::PhysicalContactOccupiedToUnoccupiedDelay::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributePhysicalContactOccupiedToUnoccupiedDelayWithValue:(NSNumber * _Nonnull)value
                                                             completion:(MTRStatusCompletion)completion
{
    [self writeAttributePhysicalContactOccupiedToUnoccupiedDelayWithValue:(NSNumber * _Nonnull) value
                                                                   params:nil
                                                               completion:completion];
}
- (void)writeAttributePhysicalContactOccupiedToUnoccupiedDelayWithValue:(NSNumber * _Nonnull)value
                                                                 params:(MTRWriteParams * _Nullable)params
                                                             completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = OccupancySensing::Attributes::PhysicalContactOccupiedToUnoccupiedDelay::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributePhysicalContactOccupiedToUnoccupiedDelayWithParams:(MTRSubscribeParams * _Nonnull)params
                                                     subscriptionEstablished:
                                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                               reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                 NSError * _Nullable error))reportHandler
{
    using TypeInfo = OccupancySensing::Attributes::PhysicalContactOccupiedToUnoccupiedDelay::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePhysicalContactOccupiedToUnoccupiedDelayWithClusterStateCache:
            (MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                                          endpoint:(NSNumber *)endpoint
                                                                             queue:(dispatch_queue_t)queue
                                                                        completion:(void (^)(NSNumber * _Nullable value,
                                                                                       NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OccupancySensing::Attributes::PhysicalContactOccupiedToUnoccupiedDelay::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePhysicalContactUnoccupiedToOccupiedDelayWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                                NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OccupancySensing::Attributes::PhysicalContactUnoccupiedToOccupiedDelay::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributePhysicalContactUnoccupiedToOccupiedDelayWithValue:(NSNumber * _Nonnull)value
                                                             completion:(MTRStatusCompletion)completion
{
    [self writeAttributePhysicalContactUnoccupiedToOccupiedDelayWithValue:(NSNumber * _Nonnull) value
                                                                   params:nil
                                                               completion:completion];
}
- (void)writeAttributePhysicalContactUnoccupiedToOccupiedDelayWithValue:(NSNumber * _Nonnull)value
                                                                 params:(MTRWriteParams * _Nullable)params
                                                             completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = OccupancySensing::Attributes::PhysicalContactUnoccupiedToOccupiedDelay::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributePhysicalContactUnoccupiedToOccupiedDelayWithParams:(MTRSubscribeParams * _Nonnull)params
                                                     subscriptionEstablished:
                                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                               reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                 NSError * _Nullable error))reportHandler
{
    using TypeInfo = OccupancySensing::Attributes::PhysicalContactUnoccupiedToOccupiedDelay::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePhysicalContactUnoccupiedToOccupiedDelayWithClusterStateCache:
            (MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                                          endpoint:(NSNumber *)endpoint
                                                                             queue:(dispatch_queue_t)queue
                                                                        completion:(void (^)(NSNumber * _Nullable value,
                                                                                       NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OccupancySensing::Attributes::PhysicalContactUnoccupiedToOccupiedDelay::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePhysicalContactUnoccupiedToOccupiedThresholdWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                                    NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OccupancySensing::Attributes::PhysicalContactUnoccupiedToOccupiedThreshold::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributePhysicalContactUnoccupiedToOccupiedThresholdWithValue:(NSNumber * _Nonnull)value
                                                                 completion:(MTRStatusCompletion)completion
{
    [self writeAttributePhysicalContactUnoccupiedToOccupiedThresholdWithValue:(NSNumber * _Nonnull) value
                                                                       params:nil
                                                                   completion:completion];
}
- (void)writeAttributePhysicalContactUnoccupiedToOccupiedThresholdWithValue:(NSNumber * _Nonnull)value
                                                                     params:(MTRWriteParams * _Nullable)params
                                                                 completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = OccupancySensing::Attributes::PhysicalContactUnoccupiedToOccupiedThreshold::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributePhysicalContactUnoccupiedToOccupiedThresholdWithParams:(MTRSubscribeParams * _Nonnull)params
                                                         subscriptionEstablished:
                                                             (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                                   reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                     NSError * _Nullable error))reportHandler
{
    using TypeInfo = OccupancySensing::Attributes::PhysicalContactUnoccupiedToOccupiedThreshold::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePhysicalContactUnoccupiedToOccupiedThresholdWithClusterStateCache:
            (MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                                              endpoint:(NSNumber *)endpoint
                                                                                 queue:(dispatch_queue_t)queue
                                                                            completion:(void (^)(NSNumber * _Nullable value,
                                                                                           NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OccupancySensing::Attributes::PhysicalContactUnoccupiedToOccupiedThreshold::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OccupancySensing::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTROccupancySensingGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OccupancySensing::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTROccupancySensingGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTROccupancySensingGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(OccupancySensingGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OccupancySensing::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OccupancySensing::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTROccupancySensingAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OccupancySensing::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTROccupancySensingAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTROccupancySensingAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(OccupancySensingAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OccupancySensing::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OccupancySensing::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTROccupancySensingEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OccupancySensing::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTROccupancySensingEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTROccupancySensingEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(OccupancySensingEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OccupancySensing::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OccupancySensing::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTROccupancySensingAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OccupancySensing::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTROccupancySensingAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTROccupancySensingAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(OccupancySensingAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OccupancySensing::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OccupancySensing::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OccupancySensing::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OccupancySensing::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = OccupancySensing::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = OccupancySensing::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OccupancySensing::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterOccupancySensing (Deprecated)

- (void)readAttributeOccupancyWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOccupancyWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeOccupancyWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeOccupancyWithParams:subscribeParams
                        subscriptionEstablished:subscriptionEstablishedHandler
                                  reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                      // Cast is safe because subclass does not add any selectors.
                                      reportHandler(static_cast<NSNumber *>(value), error);
                                  }];
}
+ (void)readAttributeOccupancyWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOccupancyWithClusterStateCache:attributeCacheContainer.realContainer
                                             endpoint:endpoint
                                                queue:queue
                                           completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               completionHandler(static_cast<NSNumber *>(value), error);
                                           }];
}

- (void)readAttributeOccupancySensorTypeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeOccupancySensorTypeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeOccupancySensorTypeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeOccupancySensorTypeWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSNumber *>(value), error);
                                            }];
}
+ (void)readAttributeOccupancySensorTypeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOccupancySensorTypeWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}

- (void)readAttributeOccupancySensorTypeBitmapWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    [self readAttributeOccupancySensorTypeBitmapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeOccupancySensorTypeBitmapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                                            params:(MTRSubscribeParams * _Nullable)params
                                           subscriptionEstablished:
                                               (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                     reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeOccupancySensorTypeBitmapWithParams:subscribeParams
                                        subscriptionEstablished:subscriptionEstablishedHandler
                                                  reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      reportHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}
+ (void)readAttributeOccupancySensorTypeBitmapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                               completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    [self readAttributeOccupancySensorTypeBitmapWithClusterStateCache:attributeCacheContainer.realContainer
                                                             endpoint:endpoint
                                                                queue:queue
                                                           completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                               // Cast is safe because subclass does not add any selectors.
                                                               completionHandler(static_cast<NSNumber *>(value), error);
                                                           }];
}

- (void)readAttributePirOccupiedToUnoccupiedDelayWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completionHandler
{
    [self readAttributePIROccupiedToUnoccupiedDelayWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributePirOccupiedToUnoccupiedDelayWithValue:(NSNumber * _Nonnull)value
                                          completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributePIROccupiedToUnoccupiedDelayWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributePirOccupiedToUnoccupiedDelayWithValue:(NSNumber * _Nonnull)value
                                                     params:(MTRWriteParams * _Nullable)params
                                          completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributePIROccupiedToUnoccupiedDelayWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributePirOccupiedToUnoccupiedDelayWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                                               params:(MTRSubscribeParams * _Nullable)params
                                              subscriptionEstablished:
                                                  (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                        reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePIROccupiedToUnoccupiedDelayWithParams:subscribeParams
                                           subscriptionEstablished:subscriptionEstablishedHandler
                                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         reportHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}
+ (void)readAttributePirOccupiedToUnoccupiedDelayWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                           endpoint:(NSNumber *)endpoint
                                                              queue:(dispatch_queue_t)queue
                                                  completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    [self readAttributePIROccupiedToUnoccupiedDelayWithClusterStateCache:attributeCacheContainer.realContainer
                                                                endpoint:endpoint
                                                                   queue:queue
                                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                  // Cast is safe because subclass does not add any selectors.
                                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                                              }];
}

- (void)readAttributePirUnoccupiedToOccupiedDelayWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completionHandler
{
    [self readAttributePIRUnoccupiedToOccupiedDelayWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributePirUnoccupiedToOccupiedDelayWithValue:(NSNumber * _Nonnull)value
                                          completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributePIRUnoccupiedToOccupiedDelayWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributePirUnoccupiedToOccupiedDelayWithValue:(NSNumber * _Nonnull)value
                                                     params:(MTRWriteParams * _Nullable)params
                                          completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributePIRUnoccupiedToOccupiedDelayWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributePirUnoccupiedToOccupiedDelayWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                                               params:(MTRSubscribeParams * _Nullable)params
                                              subscriptionEstablished:
                                                  (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                        reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePIRUnoccupiedToOccupiedDelayWithParams:subscribeParams
                                           subscriptionEstablished:subscriptionEstablishedHandler
                                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         reportHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}
+ (void)readAttributePirUnoccupiedToOccupiedDelayWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                           endpoint:(NSNumber *)endpoint
                                                              queue:(dispatch_queue_t)queue
                                                  completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    [self readAttributePIRUnoccupiedToOccupiedDelayWithClusterStateCache:attributeCacheContainer.realContainer
                                                                endpoint:endpoint
                                                                   queue:queue
                                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                  // Cast is safe because subclass does not add any selectors.
                                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                                              }];
}

- (void)readAttributePirUnoccupiedToOccupiedThresholdWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributePIRUnoccupiedToOccupiedThresholdWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributePirUnoccupiedToOccupiedThresholdWithValue:(NSNumber * _Nonnull)value
                                              completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributePIRUnoccupiedToOccupiedThresholdWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributePirUnoccupiedToOccupiedThresholdWithValue:(NSNumber * _Nonnull)value
                                                         params:(MTRWriteParams * _Nullable)params
                                              completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributePIRUnoccupiedToOccupiedThresholdWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributePirUnoccupiedToOccupiedThresholdWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                   params:(MTRSubscribeParams * _Nullable)params
                                                  subscriptionEstablished:
                                                      (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                            reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePIRUnoccupiedToOccupiedThresholdWithParams:subscribeParams
                                               subscriptionEstablished:subscriptionEstablishedHandler
                                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                             // Cast is safe because subclass does not add any selectors.
                                                             reportHandler(static_cast<NSNumber *>(value), error);
                                                         }];
}
+ (void)readAttributePirUnoccupiedToOccupiedThresholdWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                               endpoint:(NSNumber *)endpoint
                                                                  queue:(dispatch_queue_t)queue
                                                      completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))completionHandler
{
    [self readAttributePIRUnoccupiedToOccupiedThresholdWithClusterStateCache:attributeCacheContainer.realContainer
                                                                    endpoint:endpoint
                                                                       queue:queue
                                                                  completion:^(
                                                                      NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                      // Cast is safe because subclass does not add any selectors.
                                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                                  }];
}

- (void)readAttributeUltrasonicOccupiedToUnoccupiedDelayWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeUltrasonicOccupiedToUnoccupiedDelayWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeUltrasonicOccupiedToUnoccupiedDelayWithValue:(NSNumber * _Nonnull)value
                                                 completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeUltrasonicOccupiedToUnoccupiedDelayWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeUltrasonicOccupiedToUnoccupiedDelayWithValue:(NSNumber * _Nonnull)value
                                                            params:(MTRWriteParams * _Nullable)params
                                                 completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeUltrasonicOccupiedToUnoccupiedDelayWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeUltrasonicOccupiedToUnoccupiedDelayWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                      params:(MTRSubscribeParams * _Nullable)params
                                                     subscriptionEstablished:
                                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                               reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                 NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeUltrasonicOccupiedToUnoccupiedDelayWithParams:subscribeParams
                                                  subscriptionEstablished:subscriptionEstablishedHandler
                                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                // Cast is safe because subclass does not add any selectors.
                                                                reportHandler(static_cast<NSNumber *>(value), error);
                                                            }];
}
+ (void)readAttributeUltrasonicOccupiedToUnoccupiedDelayWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                                  endpoint:(NSNumber *)endpoint
                                                                     queue:(dispatch_queue_t)queue
                                                         completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeUltrasonicOccupiedToUnoccupiedDelayWithClusterStateCache:attributeCacheContainer.realContainer
                                                                       endpoint:endpoint
                                                                          queue:queue
                                                                     completion:^(
                                                                         NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                         // Cast is safe because subclass does not add any
                                                                         // selectors.
                                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                                     }];
}

- (void)readAttributeUltrasonicUnoccupiedToOccupiedDelayWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeUltrasonicUnoccupiedToOccupiedDelayWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeUltrasonicUnoccupiedToOccupiedDelayWithValue:(NSNumber * _Nonnull)value
                                                 completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeUltrasonicUnoccupiedToOccupiedDelayWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeUltrasonicUnoccupiedToOccupiedDelayWithValue:(NSNumber * _Nonnull)value
                                                            params:(MTRWriteParams * _Nullable)params
                                                 completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeUltrasonicUnoccupiedToOccupiedDelayWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeUltrasonicUnoccupiedToOccupiedDelayWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                      params:(MTRSubscribeParams * _Nullable)params
                                                     subscriptionEstablished:
                                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                               reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                 NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeUltrasonicUnoccupiedToOccupiedDelayWithParams:subscribeParams
                                                  subscriptionEstablished:subscriptionEstablishedHandler
                                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                // Cast is safe because subclass does not add any selectors.
                                                                reportHandler(static_cast<NSNumber *>(value), error);
                                                            }];
}
+ (void)readAttributeUltrasonicUnoccupiedToOccupiedDelayWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                                  endpoint:(NSNumber *)endpoint
                                                                     queue:(dispatch_queue_t)queue
                                                         completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeUltrasonicUnoccupiedToOccupiedDelayWithClusterStateCache:attributeCacheContainer.realContainer
                                                                       endpoint:endpoint
                                                                          queue:queue
                                                                     completion:^(
                                                                         NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                         // Cast is safe because subclass does not add any
                                                                         // selectors.
                                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                                     }];
}

- (void)readAttributeUltrasonicUnoccupiedToOccupiedThresholdWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                      NSError * _Nullable error))completionHandler
{
    [self readAttributeUltrasonicUnoccupiedToOccupiedThresholdWithCompletion:^(
        NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeUltrasonicUnoccupiedToOccupiedThresholdWithValue:(NSNumber * _Nonnull)value
                                                     completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeUltrasonicUnoccupiedToOccupiedThresholdWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeUltrasonicUnoccupiedToOccupiedThresholdWithValue:(NSNumber * _Nonnull)value
                                                                params:(MTRWriteParams * _Nullable)params
                                                     completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeUltrasonicUnoccupiedToOccupiedThresholdWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeUltrasonicUnoccupiedToOccupiedThresholdWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                          params:(MTRSubscribeParams * _Nullable)params
                                                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)
                                                                                     subscriptionEstablishedHandler
                                                                   reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                     NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeUltrasonicUnoccupiedToOccupiedThresholdWithParams:subscribeParams
                                                      subscriptionEstablished:subscriptionEstablishedHandler
                                                                reportHandler:^(
                                                                    NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                    // Cast is safe because subclass does not add any selectors.
                                                                    reportHandler(static_cast<NSNumber *>(value), error);
                                                                }];
}
+ (void)readAttributeUltrasonicUnoccupiedToOccupiedThresholdWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                                      endpoint:(NSNumber *)endpoint
                                                                         queue:(dispatch_queue_t)queue
                                                             completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                   NSError * _Nullable error))completionHandler
{
    [self
        readAttributeUltrasonicUnoccupiedToOccupiedThresholdWithClusterStateCache:attributeCacheContainer.realContainer
                                                                         endpoint:endpoint
                                                                            queue:queue
                                                                       completion:^(
                                                                           NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                           // Cast is safe because subclass does not add any
                                                                           // selectors.
                                                                           completionHandler(static_cast<NSNumber *>(value), error);
                                                                       }];
}

- (void)readAttributePhysicalContactOccupiedToUnoccupiedDelayWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                       NSError * _Nullable error))completionHandler
{
    [self readAttributePhysicalContactOccupiedToUnoccupiedDelayWithCompletion:^(
        NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributePhysicalContactOccupiedToUnoccupiedDelayWithValue:(NSNumber * _Nonnull)value
                                                      completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributePhysicalContactOccupiedToUnoccupiedDelayWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributePhysicalContactOccupiedToUnoccupiedDelayWithValue:(NSNumber * _Nonnull)value
                                                                 params:(MTRWriteParams * _Nullable)params
                                                      completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributePhysicalContactOccupiedToUnoccupiedDelayWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributePhysicalContactOccupiedToUnoccupiedDelayWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                           params:(MTRSubscribeParams * _Nullable)params
                                                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)
                                                                                      subscriptionEstablishedHandler
                                                                    reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                      NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePhysicalContactOccupiedToUnoccupiedDelayWithParams:subscribeParams
                                                       subscriptionEstablished:subscriptionEstablishedHandler
                                                                 reportHandler:^(
                                                                     NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                     // Cast is safe because subclass does not add any selectors.
                                                                     reportHandler(static_cast<NSNumber *>(value), error);
                                                                 }];
}
+ (void)readAttributePhysicalContactOccupiedToUnoccupiedDelayWithAttributeCache:
            (MTRAttributeCacheContainer *)attributeCacheContainer
                                                                       endpoint:(NSNumber *)endpoint
                                                                          queue:(dispatch_queue_t)queue
                                                              completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                    NSError * _Nullable error))completionHandler
{
    [self readAttributePhysicalContactOccupiedToUnoccupiedDelayWithClusterStateCache:attributeCacheContainer.realContainer
                                                                            endpoint:endpoint
                                                                               queue:queue
                                                                          completion:^(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error) {
                                                                              // Cast is safe because subclass does not add any
                                                                              // selectors.
                                                                              completionHandler(
                                                                                  static_cast<NSNumber *>(value), error);
                                                                          }];
}

- (void)readAttributePhysicalContactUnoccupiedToOccupiedDelayWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                       NSError * _Nullable error))completionHandler
{
    [self readAttributePhysicalContactUnoccupiedToOccupiedDelayWithCompletion:^(
        NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributePhysicalContactUnoccupiedToOccupiedDelayWithValue:(NSNumber * _Nonnull)value
                                                      completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributePhysicalContactUnoccupiedToOccupiedDelayWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributePhysicalContactUnoccupiedToOccupiedDelayWithValue:(NSNumber * _Nonnull)value
                                                                 params:(MTRWriteParams * _Nullable)params
                                                      completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributePhysicalContactUnoccupiedToOccupiedDelayWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributePhysicalContactUnoccupiedToOccupiedDelayWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                           params:(MTRSubscribeParams * _Nullable)params
                                                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)
                                                                                      subscriptionEstablishedHandler
                                                                    reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                      NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePhysicalContactUnoccupiedToOccupiedDelayWithParams:subscribeParams
                                                       subscriptionEstablished:subscriptionEstablishedHandler
                                                                 reportHandler:^(
                                                                     NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                     // Cast is safe because subclass does not add any selectors.
                                                                     reportHandler(static_cast<NSNumber *>(value), error);
                                                                 }];
}
+ (void)readAttributePhysicalContactUnoccupiedToOccupiedDelayWithAttributeCache:
            (MTRAttributeCacheContainer *)attributeCacheContainer
                                                                       endpoint:(NSNumber *)endpoint
                                                                          queue:(dispatch_queue_t)queue
                                                              completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                    NSError * _Nullable error))completionHandler
{
    [self readAttributePhysicalContactUnoccupiedToOccupiedDelayWithClusterStateCache:attributeCacheContainer.realContainer
                                                                            endpoint:endpoint
                                                                               queue:queue
                                                                          completion:^(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error) {
                                                                              // Cast is safe because subclass does not add any
                                                                              // selectors.
                                                                              completionHandler(
                                                                                  static_cast<NSNumber *>(value), error);
                                                                          }];
}

- (void)readAttributePhysicalContactUnoccupiedToOccupiedThresholdWithCompletionHandler:
    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePhysicalContactUnoccupiedToOccupiedThresholdWithCompletion:^(
        NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributePhysicalContactUnoccupiedToOccupiedThresholdWithValue:(NSNumber * _Nonnull)value
                                                          completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributePhysicalContactUnoccupiedToOccupiedThresholdWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributePhysicalContactUnoccupiedToOccupiedThresholdWithValue:(NSNumber * _Nonnull)value
                                                                     params:(MTRWriteParams * _Nullable)params
                                                          completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributePhysicalContactUnoccupiedToOccupiedThresholdWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributePhysicalContactUnoccupiedToOccupiedThresholdWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                               params:(MTRSubscribeParams * _Nullable)params
                                                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)
                                                                                          subscriptionEstablishedHandler
                                                                        reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                          NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePhysicalContactUnoccupiedToOccupiedThresholdWithParams:subscribeParams
                                                           subscriptionEstablished:subscriptionEstablishedHandler
                                                                     reportHandler:^(
                                                                         NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                         // Cast is safe because subclass does not add any
                                                                         // selectors.
                                                                         reportHandler(static_cast<NSNumber *>(value), error);
                                                                     }];
}
+ (void)readAttributePhysicalContactUnoccupiedToOccupiedThresholdWithAttributeCache:
            (MTRAttributeCacheContainer *)attributeCacheContainer
                                                                           endpoint:(NSNumber *)endpoint
                                                                              queue:(dispatch_queue_t)queue
                                                                  completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                        NSError * _Nullable error))completionHandler
{
    [self readAttributePhysicalContactUnoccupiedToOccupiedThresholdWithClusterStateCache:attributeCacheContainer.realContainer
                                                                                endpoint:endpoint
                                                                                   queue:queue
                                                                              completion:^(NSNumber * _Nullable value,
                                                                                  NSError * _Nullable error) {
                                                                                  // Cast is safe because subclass does not add any
                                                                                  // selectors.
                                                                                  completionHandler(
                                                                                      static_cast<NSNumber *>(value), error);
                                                                              }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterWakeOnLAN

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)readAttributeMACAddressWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WakeOnLan::Attributes::MACAddress::TypeInfo;
    return MTRReadAttribute<MTRCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMACAddressWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WakeOnLan::Attributes::MACAddress::TypeInfo;
    MTRSubscribeAttribute<MTRCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMACAddressWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(CharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WakeOnLan::Attributes::MACAddress::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WakeOnLan::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRWakeOnLANGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WakeOnLan::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRWakeOnLANGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRWakeOnLANGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(WakeOnLANGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WakeOnLan::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WakeOnLan::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRWakeOnLANAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WakeOnLan::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRWakeOnLANAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRWakeOnLANAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(WakeOnLANAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WakeOnLan::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WakeOnLan::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRWakeOnLANEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WakeOnLan::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRWakeOnLANEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRWakeOnLANEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(WakeOnLANEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WakeOnLan::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WakeOnLan::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRWakeOnLANAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WakeOnLan::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRWakeOnLANAttributeListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRWakeOnLANAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(WakeOnLANAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WakeOnLan::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WakeOnLan::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WakeOnLan::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WakeOnLan::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = WakeOnLan::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = WakeOnLan::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WakeOnLan::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterWakeOnLan
@end

@implementation MTRBaseClusterWakeOnLan (Deprecated)

- (void)readAttributeMACAddressWithCompletionHandler:(void (^)(
                                                         NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMACAddressWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)subscribeAttributeMACAddressWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMACAddressWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSString *>(value), error);
                                   }];
}
+ (void)readAttributeMACAddressWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMACAddressWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSString *>(value), error);
                                            }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterChannel

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)changeChannelWithParams:(MTRChannelClusterChangeChannelParams *)params
                     completion:(void (^)(MTRChannelClusterChangeChannelResponseParams * _Nullable data,
                                    NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRChannelClusterChangeChannelResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            ChannelClusterChangeChannelResponseCallbackType successCb, MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRChannelClusterChangeChannelResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            Channel::Commands::ChangeChannel::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.match = [self asCharSpan:params.match];

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)changeChannelByNumberWithParams:(MTRChannelClusterChangeChannelByNumberParams *)params
                             completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            Channel::Commands::ChangeChannelByNumber::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.majorNumber = params.majorNumber.unsignedShortValue;
            request.minorNumber = params.minorNumber.unsignedShortValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)skipChannelWithParams:(MTRChannelClusterSkipChannelParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            Channel::Commands::SkipChannel::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.count = params.count.shortValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeChannelListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Channel::Attributes::ChannelList::TypeInfo;
    return MTRReadAttribute<MTRChannelChannelListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeChannelListWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Channel::Attributes::ChannelList::TypeInfo;
    MTRSubscribeAttribute<MTRChannelChannelListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeChannelListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRChannelChannelListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(ChannelChannelListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Channel::Attributes::ChannelList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeLineupWithCompletion:(void (^)(MTRChannelClusterLineupInfoStruct * _Nullable value,
                                              NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Channel::Attributes::Lineup::TypeInfo;
    return MTRReadAttribute<MTRChannelLineupStructAttributeCallbackBridge, MTRChannelClusterLineupInfoStruct,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeLineupWithParams:(MTRSubscribeParams * _Nonnull)params
                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                             reportHandler:(void (^)(MTRChannelClusterLineupInfoStruct * _Nullable value,
                                               NSError * _Nullable error))reportHandler
{
    using TypeInfo = Channel::Attributes::Lineup::TypeInfo;
    MTRSubscribeAttribute<MTRChannelLineupStructAttributeCallbackSubscriptionBridge, MTRChannelClusterLineupInfoStruct,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeLineupWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                                      completion:(void (^)(MTRChannelClusterLineupInfoStruct * _Nullable value,
                                                     NSError * _Nullable error))completion
{
    auto * bridge = new MTRChannelLineupStructAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(ChannelLineupStructAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Channel::Attributes::Lineup::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCurrentChannelWithCompletion:(void (^)(MTRChannelClusterChannelInfoStruct * _Nullable value,
                                                      NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Channel::Attributes::CurrentChannel::TypeInfo;
    return MTRReadAttribute<MTRChannelCurrentChannelStructAttributeCallbackBridge, MTRChannelClusterChannelInfoStruct,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeCurrentChannelWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(MTRChannelClusterChannelInfoStruct * _Nullable value,
                                                       NSError * _Nullable error))reportHandler
{
    using TypeInfo = Channel::Attributes::CurrentChannel::TypeInfo;
    MTRSubscribeAttribute<MTRChannelCurrentChannelStructAttributeCallbackSubscriptionBridge, MTRChannelClusterChannelInfoStruct,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeCurrentChannelWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(MTRChannelClusterChannelInfoStruct * _Nullable value,
                                                             NSError * _Nullable error))completion
{
    auto * bridge = new MTRChannelCurrentChannelStructAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ChannelCurrentChannelStructAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Channel::Attributes::CurrentChannel::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Channel::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRChannelGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Channel::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRChannelGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRChannelGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ChannelGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Channel::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Channel::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRChannelAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Channel::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRChannelAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRChannelAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ChannelAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Channel::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Channel::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRChannelEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Channel::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRChannelEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRChannelEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(ChannelEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Channel::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Channel::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRChannelAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Channel::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRChannelAttributeListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRChannelAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(ChannelAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Channel::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Channel::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Channel::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Channel::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = Channel::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = Channel::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Channel::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterChannel (Deprecated)

- (void)changeChannelWithParams:(MTRChannelClusterChangeChannelParams *)params
              completionHandler:(void (^)(MTRChannelClusterChangeChannelResponseParams * _Nullable data,
                                    NSError * _Nullable error))completionHandler
{
    [self changeChannelWithParams:params
                       completion:^(MTRChannelClusterChangeChannelResponseParams * _Nullable data, NSError * _Nullable error) {
                           // Cast is safe because subclass does not add any selectors.
                           completionHandler(static_cast<MTRChannelClusterChangeChannelResponseParams *>(data), error);
                       }];
}
- (void)changeChannelByNumberWithParams:(MTRChannelClusterChangeChannelByNumberParams *)params
                      completionHandler:(MTRStatusCompletion)completionHandler
{
    [self changeChannelByNumberWithParams:params completion:completionHandler];
}
- (void)skipChannelWithParams:(MTRChannelClusterSkipChannelParams *)params completionHandler:(MTRStatusCompletion)completionHandler
{
    [self skipChannelWithParams:params completion:completionHandler];
}

- (void)readAttributeChannelListWithCompletionHandler:(void (^)(
                                                          NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeChannelListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeChannelListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeChannelListWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSArray *>(value), error);
                                    }];
}
+ (void)readAttributeChannelListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeChannelListWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSArray *>(value), error);
                                             }];
}

- (void)readAttributeLineupWithCompletionHandler:(void (^)(MTRChannelClusterLineupInfo * _Nullable value,
                                                     NSError * _Nullable error))completionHandler
{
    [self readAttributeLineupWithCompletion:^(MTRChannelClusterLineupInfoStruct * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<MTRChannelClusterLineupInfo *>(value), error);
    }];
}
- (void)subscribeAttributeLineupWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(MTRChannelClusterLineupInfo * _Nullable value,
                                                    NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeLineupWithParams:subscribeParams
                     subscriptionEstablished:subscriptionEstablishedHandler
                               reportHandler:^(MTRChannelClusterLineupInfoStruct * _Nullable value, NSError * _Nullable error) {
                                   // Cast is safe because subclass does not add any selectors.
                                   reportHandler(static_cast<MTRChannelClusterLineupInfo *>(value), error);
                               }];
}
+ (void)readAttributeLineupWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(MTRChannelClusterLineupInfo * _Nullable value,
                                                  NSError * _Nullable error))completionHandler
{
    [self
        readAttributeLineupWithClusterStateCache:attributeCacheContainer.realContainer
                                        endpoint:endpoint
                                           queue:queue
                                      completion:^(MTRChannelClusterLineupInfoStruct * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          completionHandler(static_cast<MTRChannelClusterLineupInfo *>(value), error);
                                      }];
}

- (void)readAttributeCurrentChannelWithCompletionHandler:(void (^)(MTRChannelClusterChannelInfo * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentChannelWithCompletion:^(
        MTRChannelClusterChannelInfoStruct * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<MTRChannelClusterChannelInfo *>(value), error);
    }];
}
- (void)subscribeAttributeCurrentChannelWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:(void (^)(MTRChannelClusterChannelInfo * _Nullable value,
                                                            NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeCurrentChannelWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(
                                           MTRChannelClusterChannelInfoStruct * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<MTRChannelClusterChannelInfo *>(value), error);
                                       }];
}
+ (void)readAttributeCurrentChannelWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:(void (^)(MTRChannelClusterChannelInfo * _Nullable value,
                                                          NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentChannelWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(MTRChannelClusterChannelInfoStruct * _Nullable value,
                                                    NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<MTRChannelClusterChannelInfo *>(value), error);
                                                }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterTargetNavigator

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)navigateTargetWithParams:(MTRTargetNavigatorClusterNavigateTargetParams *)params
                      completion:(void (^)(MTRTargetNavigatorClusterNavigateTargetResponseParams * _Nullable data,
                                     NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRTargetNavigatorClusterNavigateTargetResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            TargetNavigatorClusterNavigateTargetResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRTargetNavigatorClusterNavigateTargetResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            TargetNavigator::Commands::NavigateTarget::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.target = params.target.unsignedCharValue;
            if (params.data != nil) {
                auto & definedValue_0 = request.data.Emplace();
                definedValue_0 = [self asCharSpan:params.data];
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeTargetListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TargetNavigator::Attributes::TargetList::TypeInfo;
    return MTRReadAttribute<MTRTargetNavigatorTargetListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeTargetListWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TargetNavigator::Attributes::TargetList::TypeInfo;
    MTRSubscribeAttribute<MTRTargetNavigatorTargetListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeTargetListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRTargetNavigatorTargetListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(TargetNavigatorTargetListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TargetNavigator::Attributes::TargetList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCurrentTargetWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TargetNavigator::Attributes::CurrentTarget::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeCurrentTargetWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TargetNavigator::Attributes::CurrentTarget::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeCurrentTargetWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TargetNavigator::Attributes::CurrentTarget::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TargetNavigator::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRTargetNavigatorGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TargetNavigator::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRTargetNavigatorGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRTargetNavigatorGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(TargetNavigatorGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TargetNavigator::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TargetNavigator::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRTargetNavigatorAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TargetNavigator::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRTargetNavigatorAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRTargetNavigatorAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(TargetNavigatorAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TargetNavigator::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TargetNavigator::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRTargetNavigatorEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TargetNavigator::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRTargetNavigatorEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRTargetNavigatorEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(TargetNavigatorEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TargetNavigator::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TargetNavigator::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRTargetNavigatorAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TargetNavigator::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRTargetNavigatorAttributeListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRTargetNavigatorAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(TargetNavigatorAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TargetNavigator::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TargetNavigator::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TargetNavigator::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TargetNavigator::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = TargetNavigator::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = TargetNavigator::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TargetNavigator::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterTargetNavigator (Deprecated)

- (void)navigateTargetWithParams:(MTRTargetNavigatorClusterNavigateTargetParams *)params
               completionHandler:(void (^)(MTRTargetNavigatorClusterNavigateTargetResponseParams * _Nullable data,
                                     NSError * _Nullable error))completionHandler
{
    [self navigateTargetWithParams:params
                        completion:^(
                            MTRTargetNavigatorClusterNavigateTargetResponseParams * _Nullable data, NSError * _Nullable error) {
                            // Cast is safe because subclass does not add any selectors.
                            completionHandler(static_cast<MTRTargetNavigatorClusterNavigateTargetResponseParams *>(data), error);
                        }];
}

- (void)readAttributeTargetListWithCompletionHandler:(void (^)(
                                                         NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeTargetListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeTargetListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeTargetListWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSArray *>(value), error);
                                   }];
}
+ (void)readAttributeTargetListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeTargetListWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSArray *>(value), error);
                                            }];
}

- (void)readAttributeCurrentTargetWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentTargetWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeCurrentTargetWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeCurrentTargetWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributeCurrentTargetWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentTargetWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterMediaPlayback

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)playWithCompletion:(void (^)(
                               MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion
{
    [self playWithParams:nil completion:completion];
}
- (void)playWithParams:(MTRMediaPlaybackClusterPlayParams * _Nullable)params
            completion:
                (void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRMediaPlaybackClusterPlaybackResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            MediaPlaybackClusterPlaybackResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRMediaPlaybackClusterPlaybackResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            MediaPlayback::Commands::Play::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)pauseWithCompletion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data,
                                NSError * _Nullable error))completion
{
    [self pauseWithParams:nil completion:completion];
}
- (void)pauseWithParams:(MTRMediaPlaybackClusterPauseParams * _Nullable)params
             completion:
                 (void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRMediaPlaybackClusterPlaybackResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            MediaPlaybackClusterPlaybackResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRMediaPlaybackClusterPlaybackResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            MediaPlayback::Commands::Pause::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)stopWithCompletion:(void (^)(
                               MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion
{
    [self stopWithParams:nil completion:completion];
}
- (void)stopWithParams:(MTRMediaPlaybackClusterStopParams * _Nullable)params
            completion:
                (void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRMediaPlaybackClusterPlaybackResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            MediaPlaybackClusterPlaybackResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRMediaPlaybackClusterPlaybackResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            MediaPlayback::Commands::Stop::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)startOverWithCompletion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data,
                                    NSError * _Nullable error))completion
{
    [self startOverWithParams:nil completion:completion];
}
- (void)startOverWithParams:(MTRMediaPlaybackClusterStartOverParams * _Nullable)params
                 completion:
                     (void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRMediaPlaybackClusterPlaybackResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            MediaPlaybackClusterPlaybackResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRMediaPlaybackClusterPlaybackResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            MediaPlayback::Commands::StartOver::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)previousWithCompletion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data,
                                   NSError * _Nullable error))completion
{
    [self previousWithParams:nil completion:completion];
}
- (void)previousWithParams:(MTRMediaPlaybackClusterPreviousParams * _Nullable)params
                completion:
                    (void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRMediaPlaybackClusterPlaybackResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            MediaPlaybackClusterPlaybackResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRMediaPlaybackClusterPlaybackResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            MediaPlayback::Commands::Previous::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)nextWithCompletion:(void (^)(
                               MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion
{
    [self nextWithParams:nil completion:completion];
}
- (void)nextWithParams:(MTRMediaPlaybackClusterNextParams * _Nullable)params
            completion:
                (void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRMediaPlaybackClusterPlaybackResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            MediaPlaybackClusterPlaybackResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRMediaPlaybackClusterPlaybackResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            MediaPlayback::Commands::Next::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)rewindWithCompletion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data,
                                 NSError * _Nullable error))completion
{
    [self rewindWithParams:nil completion:completion];
}
- (void)rewindWithParams:(MTRMediaPlaybackClusterRewindParams * _Nullable)params
              completion:
                  (void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRMediaPlaybackClusterPlaybackResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            MediaPlaybackClusterPlaybackResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRMediaPlaybackClusterPlaybackResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            MediaPlayback::Commands::Rewind::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)fastForwardWithCompletion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data,
                                      NSError * _Nullable error))completion
{
    [self fastForwardWithParams:nil completion:completion];
}
- (void)fastForwardWithParams:(MTRMediaPlaybackClusterFastForwardParams * _Nullable)params
                   completion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data,
                                  NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRMediaPlaybackClusterPlaybackResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            MediaPlaybackClusterPlaybackResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRMediaPlaybackClusterPlaybackResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            MediaPlayback::Commands::FastForward::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)skipForwardWithParams:(MTRMediaPlaybackClusterSkipForwardParams *)params
                   completion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data,
                                  NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRMediaPlaybackClusterPlaybackResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            MediaPlaybackClusterPlaybackResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRMediaPlaybackClusterPlaybackResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            MediaPlayback::Commands::SkipForward::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.deltaPositionMilliseconds = params.deltaPositionMilliseconds.unsignedLongLongValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)skipBackwardWithParams:(MTRMediaPlaybackClusterSkipBackwardParams *)params
                    completion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data,
                                   NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRMediaPlaybackClusterPlaybackResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            MediaPlaybackClusterPlaybackResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRMediaPlaybackClusterPlaybackResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            MediaPlayback::Commands::SkipBackward::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.deltaPositionMilliseconds = params.deltaPositionMilliseconds.unsignedLongLongValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)seekWithParams:(MTRMediaPlaybackClusterSeekParams *)params
            completion:
                (void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRMediaPlaybackClusterPlaybackResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            MediaPlaybackClusterPlaybackResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRMediaPlaybackClusterPlaybackResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            MediaPlayback::Commands::Seek::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.position = params.position.unsignedLongLongValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeCurrentStateWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = MediaPlayback::Attributes::CurrentState::TypeInfo;
    return MTRReadAttribute<MTRMediaPlaybackClusterPlaybackStateEnumAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeCurrentStateWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = MediaPlayback::Attributes::CurrentState::TypeInfo;
    MTRSubscribeAttribute<MTRMediaPlaybackClusterPlaybackStateEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeCurrentStateWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRMediaPlaybackClusterPlaybackStateEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(MediaPlaybackClusterPlaybackStateEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = MediaPlayback::Attributes::CurrentState::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeStartTimeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = MediaPlayback::Attributes::StartTime::TypeInfo;
    return MTRReadAttribute<MTRNullableInt64uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeStartTimeWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = MediaPlayback::Attributes::StartTime::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt64uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeStartTimeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt64uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt64uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = MediaPlayback::Attributes::StartTime::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeDurationWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = MediaPlayback::Attributes::Duration::TypeInfo;
    return MTRReadAttribute<MTRNullableInt64uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeDurationWithParams:(MTRSubscribeParams * _Nonnull)params
                     subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                               reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = MediaPlayback::Attributes::Duration::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt64uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeDurationWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                        completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt64uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt64uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = MediaPlayback::Attributes::Duration::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSampledPositionWithCompletion:(void (^)(MTRMediaPlaybackClusterPlaybackPositionStruct * _Nullable value,
                                                       NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = MediaPlayback::Attributes::SampledPosition::TypeInfo;
    return MTRReadAttribute<MTRMediaPlaybackSampledPositionStructAttributeCallbackBridge,
        MTRMediaPlaybackClusterPlaybackPositionStruct, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeSampledPositionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(MTRMediaPlaybackClusterPlaybackPositionStruct * _Nullable value,
                                                        NSError * _Nullable error))reportHandler
{
    using TypeInfo = MediaPlayback::Attributes::SampledPosition::TypeInfo;
    MTRSubscribeAttribute<MTRMediaPlaybackSampledPositionStructAttributeCallbackSubscriptionBridge,
        MTRMediaPlaybackClusterPlaybackPositionStruct, TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler,
        self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeSampledPositionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:(void (^)(MTRMediaPlaybackClusterPlaybackPositionStruct * _Nullable value,
                                                              NSError * _Nullable error))completion
{
    auto * bridge = new MTRMediaPlaybackSampledPositionStructAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(MediaPlaybackSampledPositionStructAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = MediaPlayback::Attributes::SampledPosition::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePlaybackSpeedWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = MediaPlayback::Attributes::PlaybackSpeed::TypeInfo;
    return MTRReadAttribute<MTRFloatAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePlaybackSpeedWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = MediaPlayback::Attributes::PlaybackSpeed::TypeInfo;
    MTRSubscribeAttribute<MTRFloatAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePlaybackSpeedWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRFloatAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(FloatAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = MediaPlayback::Attributes::PlaybackSpeed::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSeekRangeEndWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = MediaPlayback::Attributes::SeekRangeEnd::TypeInfo;
    return MTRReadAttribute<MTRNullableInt64uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeSeekRangeEndWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = MediaPlayback::Attributes::SeekRangeEnd::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt64uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeSeekRangeEndWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt64uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt64uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = MediaPlayback::Attributes::SeekRangeEnd::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSeekRangeStartWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = MediaPlayback::Attributes::SeekRangeStart::TypeInfo;
    return MTRReadAttribute<MTRNullableInt64uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeSeekRangeStartWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = MediaPlayback::Attributes::SeekRangeStart::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt64uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeSeekRangeStartWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt64uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt64uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = MediaPlayback::Attributes::SeekRangeStart::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = MediaPlayback::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRMediaPlaybackGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = MediaPlayback::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRMediaPlaybackGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRMediaPlaybackGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(MediaPlaybackGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = MediaPlayback::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = MediaPlayback::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRMediaPlaybackAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = MediaPlayback::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRMediaPlaybackAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRMediaPlaybackAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(MediaPlaybackAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = MediaPlayback::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = MediaPlayback::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRMediaPlaybackEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = MediaPlayback::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRMediaPlaybackEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRMediaPlaybackEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(MediaPlaybackEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = MediaPlayback::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = MediaPlayback::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRMediaPlaybackAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = MediaPlayback::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRMediaPlaybackAttributeListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRMediaPlaybackAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(MediaPlaybackAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = MediaPlayback::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = MediaPlayback::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = MediaPlayback::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = MediaPlayback::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = MediaPlayback::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = MediaPlayback::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = MediaPlayback::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterMediaPlayback (Deprecated)

- (void)playWithParams:(MTRMediaPlaybackClusterPlayParams * _Nullable)params
     completionHandler:
         (void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler
{
    [self playWithParams:params
              completion:^(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error) {
                  // Cast is safe because subclass does not add any selectors.
                  completionHandler(static_cast<MTRMediaPlaybackClusterPlaybackResponseParams *>(data), error);
              }];
}
- (void)playWithCompletionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data,
                                      NSError * _Nullable error))completionHandler
{
    [self playWithParams:nil completionHandler:completionHandler];
}
- (void)pauseWithParams:(MTRMediaPlaybackClusterPauseParams * _Nullable)params
      completionHandler:
          (void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler
{
    [self pauseWithParams:params
               completion:^(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error) {
                   // Cast is safe because subclass does not add any selectors.
                   completionHandler(static_cast<MTRMediaPlaybackClusterPlaybackResponseParams *>(data), error);
               }];
}
- (void)pauseWithCompletionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data,
                                       NSError * _Nullable error))completionHandler
{
    [self pauseWithParams:nil completionHandler:completionHandler];
}
- (void)stopPlaybackWithParams:(MTRMediaPlaybackClusterStopPlaybackParams * _Nullable)params
             completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data,
                                   NSError * _Nullable error))completionHandler
{
    [self stopWithParams:params
              completion:^(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error) {
                  // Cast is safe because subclass does not add any selectors.
                  completionHandler(static_cast<MTRMediaPlaybackClusterPlaybackResponseParams *>(data), error);
              }];
}
- (void)stopPlaybackWithCompletionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data,
                                              NSError * _Nullable error))completionHandler
{
    [self stopPlaybackWithParams:nil completionHandler:completionHandler];
}
- (void)startOverWithParams:(MTRMediaPlaybackClusterStartOverParams * _Nullable)params
          completionHandler:
              (void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler
{
    [self startOverWithParams:params
                   completion:^(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error) {
                       // Cast is safe because subclass does not add any selectors.
                       completionHandler(static_cast<MTRMediaPlaybackClusterPlaybackResponseParams *>(data), error);
                   }];
}
- (void)startOverWithCompletionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data,
                                           NSError * _Nullable error))completionHandler
{
    [self startOverWithParams:nil completionHandler:completionHandler];
}
- (void)previousWithParams:(MTRMediaPlaybackClusterPreviousParams * _Nullable)params
         completionHandler:
             (void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler
{
    [self previousWithParams:params
                  completion:^(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error) {
                      // Cast is safe because subclass does not add any selectors.
                      completionHandler(static_cast<MTRMediaPlaybackClusterPlaybackResponseParams *>(data), error);
                  }];
}
- (void)previousWithCompletionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data,
                                          NSError * _Nullable error))completionHandler
{
    [self previousWithParams:nil completionHandler:completionHandler];
}
- (void)nextWithParams:(MTRMediaPlaybackClusterNextParams * _Nullable)params
     completionHandler:
         (void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler
{
    [self nextWithParams:params
              completion:^(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error) {
                  // Cast is safe because subclass does not add any selectors.
                  completionHandler(static_cast<MTRMediaPlaybackClusterPlaybackResponseParams *>(data), error);
              }];
}
- (void)nextWithCompletionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data,
                                      NSError * _Nullable error))completionHandler
{
    [self nextWithParams:nil completionHandler:completionHandler];
}
- (void)rewindWithParams:(MTRMediaPlaybackClusterRewindParams * _Nullable)params
       completionHandler:
           (void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler
{
    [self rewindWithParams:params
                completion:^(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error) {
                    // Cast is safe because subclass does not add any selectors.
                    completionHandler(static_cast<MTRMediaPlaybackClusterPlaybackResponseParams *>(data), error);
                }];
}
- (void)rewindWithCompletionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data,
                                        NSError * _Nullable error))completionHandler
{
    [self rewindWithParams:nil completionHandler:completionHandler];
}
- (void)fastForwardWithParams:(MTRMediaPlaybackClusterFastForwardParams * _Nullable)params
            completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data,
                                  NSError * _Nullable error))completionHandler
{
    [self fastForwardWithParams:params
                     completion:^(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error) {
                         // Cast is safe because subclass does not add any selectors.
                         completionHandler(static_cast<MTRMediaPlaybackClusterPlaybackResponseParams *>(data), error);
                     }];
}
- (void)fastForwardWithCompletionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data,
                                             NSError * _Nullable error))completionHandler
{
    [self fastForwardWithParams:nil completionHandler:completionHandler];
}
- (void)skipForwardWithParams:(MTRMediaPlaybackClusterSkipForwardParams *)params
            completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data,
                                  NSError * _Nullable error))completionHandler
{
    [self skipForwardWithParams:params
                     completion:^(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error) {
                         // Cast is safe because subclass does not add any selectors.
                         completionHandler(static_cast<MTRMediaPlaybackClusterPlaybackResponseParams *>(data), error);
                     }];
}
- (void)skipBackwardWithParams:(MTRMediaPlaybackClusterSkipBackwardParams *)params
             completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data,
                                   NSError * _Nullable error))completionHandler
{
    [self skipBackwardWithParams:params
                      completion:^(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error) {
                          // Cast is safe because subclass does not add any selectors.
                          completionHandler(static_cast<MTRMediaPlaybackClusterPlaybackResponseParams *>(data), error);
                      }];
}
- (void)seekWithParams:(MTRMediaPlaybackClusterSeekParams *)params
     completionHandler:
         (void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler
{
    [self seekWithParams:params
              completion:^(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error) {
                  // Cast is safe because subclass does not add any selectors.
                  completionHandler(static_cast<MTRMediaPlaybackClusterPlaybackResponseParams *>(data), error);
              }];
}

- (void)readAttributeCurrentStateWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentStateWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeCurrentStateWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeCurrentStateWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributeCurrentStateWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentStateWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributeStartTimeWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeStartTimeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeStartTimeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeStartTimeWithParams:subscribeParams
                        subscriptionEstablished:subscriptionEstablishedHandler
                                  reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                      // Cast is safe because subclass does not add any selectors.
                                      reportHandler(static_cast<NSNumber *>(value), error);
                                  }];
}
+ (void)readAttributeStartTimeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeStartTimeWithClusterStateCache:attributeCacheContainer.realContainer
                                             endpoint:endpoint
                                                queue:queue
                                           completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               completionHandler(static_cast<NSNumber *>(value), error);
                                           }];
}

- (void)readAttributeDurationWithCompletionHandler:(void (^)(
                                                       NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDurationWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeDurationWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeDurationWithParams:subscribeParams
                       subscriptionEstablished:subscriptionEstablishedHandler
                                 reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                     // Cast is safe because subclass does not add any selectors.
                                     reportHandler(static_cast<NSNumber *>(value), error);
                                 }];
}
+ (void)readAttributeDurationWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDurationWithClusterStateCache:attributeCacheContainer.realContainer
                                            endpoint:endpoint
                                               queue:queue
                                          completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              completionHandler(static_cast<NSNumber *>(value), error);
                                          }];
}

- (void)readAttributeSampledPositionWithCompletionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackPosition * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeSampledPositionWithCompletion:^(
        MTRMediaPlaybackClusterPlaybackPositionStruct * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<MTRMediaPlaybackClusterPlaybackPosition *>(value), error);
    }];
}
- (void)subscribeAttributeSampledPositionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:(void (^)(MTRMediaPlaybackClusterPlaybackPosition * _Nullable value,
                                                             NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeSampledPositionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(MTRMediaPlaybackClusterPlaybackPositionStruct * _Nullable value,
                                            NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<MTRMediaPlaybackClusterPlaybackPosition *>(value), error);
                                        }];
}
+ (void)readAttributeSampledPositionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackPosition * _Nullable value,
                                                           NSError * _Nullable error))completionHandler
{
    [self readAttributeSampledPositionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(MTRMediaPlaybackClusterPlaybackPositionStruct * _Nullable value,
                                                     NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(
                                                         static_cast<MTRMediaPlaybackClusterPlaybackPosition *>(value), error);
                                                 }];
}

- (void)readAttributePlaybackSpeedWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePlaybackSpeedWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributePlaybackSpeedWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePlaybackSpeedWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributePlaybackSpeedWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePlaybackSpeedWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributeSeekRangeEndWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSeekRangeEndWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeSeekRangeEndWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeSeekRangeEndWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributeSeekRangeEndWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSeekRangeEndWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributeSeekRangeStartWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeSeekRangeStartWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeSeekRangeStartWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeSeekRangeStartWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSNumber *>(value), error);
                                       }];
}
+ (void)readAttributeSeekRangeStartWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeSeekRangeStartWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSNumber *>(value), error);
                                                }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterMediaInput

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)selectInputWithParams:(MTRMediaInputClusterSelectInputParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            MediaInput::Commands::SelectInput::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.index = params.index.unsignedCharValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)showInputStatusWithCompletion:(MTRStatusCompletion)completion
{
    [self showInputStatusWithParams:nil completion:completion];
}
- (void)showInputStatusWithParams:(MTRMediaInputClusterShowInputStatusParams * _Nullable)params
                       completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            MediaInput::Commands::ShowInputStatus::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)hideInputStatusWithCompletion:(MTRStatusCompletion)completion
{
    [self hideInputStatusWithParams:nil completion:completion];
}
- (void)hideInputStatusWithParams:(MTRMediaInputClusterHideInputStatusParams * _Nullable)params
                       completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            MediaInput::Commands::HideInputStatus::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)renameInputWithParams:(MTRMediaInputClusterRenameInputParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            MediaInput::Commands::RenameInput::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.index = params.index.unsignedCharValue;
            request.name = [self asCharSpan:params.name];

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeInputListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = MediaInput::Attributes::InputList::TypeInfo;
    return MTRReadAttribute<MTRMediaInputInputListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeInputListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = MediaInput::Attributes::InputList::TypeInfo;
    MTRSubscribeAttribute<MTRMediaInputInputListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeInputListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRMediaInputInputListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(MediaInputInputListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = MediaInput::Attributes::InputList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCurrentInputWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = MediaInput::Attributes::CurrentInput::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeCurrentInputWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = MediaInput::Attributes::CurrentInput::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeCurrentInputWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = MediaInput::Attributes::CurrentInput::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = MediaInput::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRMediaInputGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = MediaInput::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRMediaInputGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRMediaInputGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(MediaInputGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = MediaInput::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = MediaInput::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRMediaInputAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = MediaInput::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRMediaInputAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRMediaInputAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(MediaInputAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = MediaInput::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = MediaInput::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRMediaInputEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = MediaInput::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRMediaInputEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRMediaInputEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(MediaInputEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = MediaInput::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = MediaInput::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRMediaInputAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = MediaInput::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRMediaInputAttributeListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRMediaInputAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(MediaInputAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = MediaInput::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = MediaInput::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = MediaInput::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = MediaInput::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = MediaInput::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = MediaInput::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = MediaInput::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterMediaInput (Deprecated)

- (void)selectInputWithParams:(MTRMediaInputClusterSelectInputParams *)params
            completionHandler:(MTRStatusCompletion)completionHandler
{
    [self selectInputWithParams:params completion:completionHandler];
}
- (void)showInputStatusWithParams:(MTRMediaInputClusterShowInputStatusParams * _Nullable)params
                completionHandler:(MTRStatusCompletion)completionHandler
{
    [self showInputStatusWithParams:params completion:completionHandler];
}
- (void)showInputStatusWithCompletionHandler:(MTRStatusCompletion)completionHandler
{
    [self showInputStatusWithParams:nil completionHandler:completionHandler];
}
- (void)hideInputStatusWithParams:(MTRMediaInputClusterHideInputStatusParams * _Nullable)params
                completionHandler:(MTRStatusCompletion)completionHandler
{
    [self hideInputStatusWithParams:params completion:completionHandler];
}
- (void)hideInputStatusWithCompletionHandler:(MTRStatusCompletion)completionHandler
{
    [self hideInputStatusWithParams:nil completionHandler:completionHandler];
}
- (void)renameInputWithParams:(MTRMediaInputClusterRenameInputParams *)params
            completionHandler:(MTRStatusCompletion)completionHandler
{
    [self renameInputWithParams:params completion:completionHandler];
}

- (void)readAttributeInputListWithCompletionHandler:(void (^)(
                                                        NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInputListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeInputListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeInputListWithParams:subscribeParams
                        subscriptionEstablished:subscriptionEstablishedHandler
                                  reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                      // Cast is safe because subclass does not add any selectors.
                                      reportHandler(static_cast<NSArray *>(value), error);
                                  }];
}
+ (void)readAttributeInputListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInputListWithClusterStateCache:attributeCacheContainer.realContainer
                                             endpoint:endpoint
                                                queue:queue
                                           completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               completionHandler(static_cast<NSArray *>(value), error);
                                           }];
}

- (void)readAttributeCurrentInputWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentInputWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeCurrentInputWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeCurrentInputWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributeCurrentInputWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentInputWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterLowPower

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)sleepWithCompletion:(MTRStatusCompletion)completion
{
    [self sleepWithParams:nil completion:completion];
}
- (void)sleepWithParams:(MTRLowPowerClusterSleepParams * _Nullable)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            LowPower::Commands::Sleep::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = LowPower::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRLowPowerGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = LowPower::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRLowPowerGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRLowPowerGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(LowPowerGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LowPower::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = LowPower::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRLowPowerAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = LowPower::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRLowPowerAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRLowPowerAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(LowPowerAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LowPower::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = LowPower::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRLowPowerEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = LowPower::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRLowPowerEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRLowPowerEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(LowPowerEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LowPower::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = LowPower::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRLowPowerAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = LowPower::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRLowPowerAttributeListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRLowPowerAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(LowPowerAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LowPower::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = LowPower::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = LowPower::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LowPower::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = LowPower::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = LowPower::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LowPower::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterLowPower (Deprecated)

- (void)sleepWithParams:(MTRLowPowerClusterSleepParams * _Nullable)params completionHandler:(MTRStatusCompletion)completionHandler
{
    [self sleepWithParams:params completion:completionHandler];
}
- (void)sleepWithCompletionHandler:(MTRStatusCompletion)completionHandler
{
    [self sleepWithParams:nil completionHandler:completionHandler];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterKeypadInput

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)sendKeyWithParams:(MTRKeypadInputClusterSendKeyParams *)params
               completion:
                   (void (^)(MTRKeypadInputClusterSendKeyResponseParams * _Nullable data, NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRKeypadInputClusterSendKeyResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, KeypadInputClusterSendKeyResponseCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRKeypadInputClusterSendKeyResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            KeypadInput::Commands::SendKey::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.keyCode = static_cast<std::remove_reference_t<decltype(request.keyCode)>>(params.keyCode.unsignedCharValue);

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = KeypadInput::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRKeypadInputGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = KeypadInput::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRKeypadInputGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRKeypadInputGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(KeypadInputGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = KeypadInput::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = KeypadInput::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRKeypadInputAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = KeypadInput::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRKeypadInputAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRKeypadInputAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(KeypadInputAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = KeypadInput::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = KeypadInput::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRKeypadInputEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = KeypadInput::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRKeypadInputEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRKeypadInputEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(KeypadInputEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = KeypadInput::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = KeypadInput::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRKeypadInputAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = KeypadInput::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRKeypadInputAttributeListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRKeypadInputAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(KeypadInputAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = KeypadInput::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = KeypadInput::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = KeypadInput::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = KeypadInput::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = KeypadInput::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = KeypadInput::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = KeypadInput::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterKeypadInput (Deprecated)

- (void)sendKeyWithParams:(MTRKeypadInputClusterSendKeyParams *)params
        completionHandler:
            (void (^)(MTRKeypadInputClusterSendKeyResponseParams * _Nullable data, NSError * _Nullable error))completionHandler
{
    [self sendKeyWithParams:params
                 completion:^(MTRKeypadInputClusterSendKeyResponseParams * _Nullable data, NSError * _Nullable error) {
                     // Cast is safe because subclass does not add any selectors.
                     completionHandler(static_cast<MTRKeypadInputClusterSendKeyResponseParams *>(data), error);
                 }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterContentLauncher

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)launchContentWithParams:(MTRContentLauncherClusterLaunchContentParams *)params
                     completion:(void (^)(MTRContentLauncherClusterLauncherResponseParams * _Nullable data,
                                    NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRContentLauncherClusterLauncherResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            ContentLauncherClusterLauncherResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRContentLauncherClusterLauncherResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            ContentLauncher::Commands::LaunchContent::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            {
                using ListType_1 = std::remove_reference_t<decltype(request.search.parameterList)>;
                using ListMemberType_1 = ListMemberTypeGetter<ListType_1>::Type;
                if (params.search.parameterList.count != 0) {
                    auto * listHolder_1 = new ListHolder<ListMemberType_1>(params.search.parameterList.count);
                    if (listHolder_1 == nullptr || listHolder_1->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_1);
                    for (size_t i_1 = 0; i_1 < params.search.parameterList.count; ++i_1) {
                        if (![params.search.parameterList[i_1] isKindOfClass:[MTRContentLauncherClusterParameterStruct class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_1 = (MTRContentLauncherClusterParameterStruct *) params.search.parameterList[i_1];
                        listHolder_1->mList[i_1].type
                            = static_cast<std::remove_reference_t<decltype(listHolder_1->mList[i_1].type)>>(
                                element_1.type.unsignedCharValue);
                        listHolder_1->mList[i_1].value = [self asCharSpan:element_1.value];
                        if (element_1.externalIDList != nil) {
                            auto & definedValue_3 = listHolder_1->mList[i_1].externalIDList.Emplace();
                            {
                                using ListType_4 = std::remove_reference_t<decltype(definedValue_3)>;
                                using ListMemberType_4 = ListMemberTypeGetter<ListType_4>::Type;
                                if (element_1.externalIDList.count != 0) {
                                    auto * listHolder_4 = new ListHolder<ListMemberType_4>(element_1.externalIDList.count);
                                    if (listHolder_4 == nullptr || listHolder_4->mList == nullptr) {
                                        return CHIP_ERROR_INVALID_ARGUMENT;
                                    }
                                    listFreer.add(listHolder_4);
                                    for (size_t i_4 = 0; i_4 < element_1.externalIDList.count; ++i_4) {
                                        if (![element_1.externalIDList[i_4]
                                                isKindOfClass:[MTRContentLauncherClusterAdditionalInfoStruct class]]) {
                                            // Wrong kind of value.
                                            return CHIP_ERROR_INVALID_ARGUMENT;
                                        }
                                        auto element_4
                                            = (MTRContentLauncherClusterAdditionalInfoStruct *) element_1.externalIDList[i_4];
                                        listHolder_4->mList[i_4].name = [self asCharSpan:element_4.name];
                                        listHolder_4->mList[i_4].value = [self asCharSpan:element_4.value];
                                    }
                                    definedValue_3 = ListType_4(listHolder_4->mList, element_1.externalIDList.count);
                                } else {
                                    definedValue_3 = ListType_4();
                                }
                            }
                        }
                    }
                    request.search.parameterList = ListType_1(listHolder_1->mList, params.search.parameterList.count);
                } else {
                    request.search.parameterList = ListType_1();
                }
            }
            request.autoPlay = params.autoPlay.boolValue;
            if (params.data != nil) {
                auto & definedValue_0 = request.data.Emplace();
                definedValue_0 = [self asCharSpan:params.data];
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)launchURLWithParams:(MTRContentLauncherClusterLaunchURLParams *)params
                 completion:(void (^)(MTRContentLauncherClusterLauncherResponseParams * _Nullable data,
                                NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRContentLauncherClusterLauncherResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            ContentLauncherClusterLauncherResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRContentLauncherClusterLauncherResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            ContentLauncher::Commands::LaunchURL::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.contentURL = [self asCharSpan:params.contentURL];
            if (params.displayString != nil) {
                auto & definedValue_0 = request.displayString.Emplace();
                definedValue_0 = [self asCharSpan:params.displayString];
            }
            if (params.brandingInformation != nil) {
                auto & definedValue_0 = request.brandingInformation.Emplace();
                definedValue_0.providerName = [self asCharSpan:params.brandingInformation.providerName];
                if (params.brandingInformation.background != nil) {
                    auto & definedValue_2 = definedValue_0.background.Emplace();
                    if (params.brandingInformation.background.imageURL != nil) {
                        auto & definedValue_4 = definedValue_2.imageURL.Emplace();
                        definedValue_4 = [self asCharSpan:params.brandingInformation.background.imageURL];
                    }
                    if (params.brandingInformation.background.color != nil) {
                        auto & definedValue_4 = definedValue_2.color.Emplace();
                        definedValue_4 = [self asCharSpan:params.brandingInformation.background.color];
                    }
                    if (params.brandingInformation.background.size != nil) {
                        auto & definedValue_4 = definedValue_2.size.Emplace();
                        definedValue_4.width = params.brandingInformation.background.size.width.doubleValue;
                        definedValue_4.height = params.brandingInformation.background.size.height.doubleValue;
                        definedValue_4.metric = static_cast<std::remove_reference_t<decltype(definedValue_4.metric)>>(
                            params.brandingInformation.background.size.metric.unsignedCharValue);
                    }
                }
                if (params.brandingInformation.logo != nil) {
                    auto & definedValue_2 = definedValue_0.logo.Emplace();
                    if (params.brandingInformation.logo.imageURL != nil) {
                        auto & definedValue_4 = definedValue_2.imageURL.Emplace();
                        definedValue_4 = [self asCharSpan:params.brandingInformation.logo.imageURL];
                    }
                    if (params.brandingInformation.logo.color != nil) {
                        auto & definedValue_4 = definedValue_2.color.Emplace();
                        definedValue_4 = [self asCharSpan:params.brandingInformation.logo.color];
                    }
                    if (params.brandingInformation.logo.size != nil) {
                        auto & definedValue_4 = definedValue_2.size.Emplace();
                        definedValue_4.width = params.brandingInformation.logo.size.width.doubleValue;
                        definedValue_4.height = params.brandingInformation.logo.size.height.doubleValue;
                        definedValue_4.metric = static_cast<std::remove_reference_t<decltype(definedValue_4.metric)>>(
                            params.brandingInformation.logo.size.metric.unsignedCharValue);
                    }
                }
                if (params.brandingInformation.progressBar != nil) {
                    auto & definedValue_2 = definedValue_0.progressBar.Emplace();
                    if (params.brandingInformation.progressBar.imageURL != nil) {
                        auto & definedValue_4 = definedValue_2.imageURL.Emplace();
                        definedValue_4 = [self asCharSpan:params.brandingInformation.progressBar.imageURL];
                    }
                    if (params.brandingInformation.progressBar.color != nil) {
                        auto & definedValue_4 = definedValue_2.color.Emplace();
                        definedValue_4 = [self asCharSpan:params.brandingInformation.progressBar.color];
                    }
                    if (params.brandingInformation.progressBar.size != nil) {
                        auto & definedValue_4 = definedValue_2.size.Emplace();
                        definedValue_4.width = params.brandingInformation.progressBar.size.width.doubleValue;
                        definedValue_4.height = params.brandingInformation.progressBar.size.height.doubleValue;
                        definedValue_4.metric = static_cast<std::remove_reference_t<decltype(definedValue_4.metric)>>(
                            params.brandingInformation.progressBar.size.metric.unsignedCharValue);
                    }
                }
                if (params.brandingInformation.splash != nil) {
                    auto & definedValue_2 = definedValue_0.splash.Emplace();
                    if (params.brandingInformation.splash.imageURL != nil) {
                        auto & definedValue_4 = definedValue_2.imageURL.Emplace();
                        definedValue_4 = [self asCharSpan:params.brandingInformation.splash.imageURL];
                    }
                    if (params.brandingInformation.splash.color != nil) {
                        auto & definedValue_4 = definedValue_2.color.Emplace();
                        definedValue_4 = [self asCharSpan:params.brandingInformation.splash.color];
                    }
                    if (params.brandingInformation.splash.size != nil) {
                        auto & definedValue_4 = definedValue_2.size.Emplace();
                        definedValue_4.width = params.brandingInformation.splash.size.width.doubleValue;
                        definedValue_4.height = params.brandingInformation.splash.size.height.doubleValue;
                        definedValue_4.metric = static_cast<std::remove_reference_t<decltype(definedValue_4.metric)>>(
                            params.brandingInformation.splash.size.metric.unsignedCharValue);
                    }
                }
                if (params.brandingInformation.waterMark != nil) {
                    auto & definedValue_2 = definedValue_0.waterMark.Emplace();
                    if (params.brandingInformation.waterMark.imageURL != nil) {
                        auto & definedValue_4 = definedValue_2.imageURL.Emplace();
                        definedValue_4 = [self asCharSpan:params.brandingInformation.waterMark.imageURL];
                    }
                    if (params.brandingInformation.waterMark.color != nil) {
                        auto & definedValue_4 = definedValue_2.color.Emplace();
                        definedValue_4 = [self asCharSpan:params.brandingInformation.waterMark.color];
                    }
                    if (params.brandingInformation.waterMark.size != nil) {
                        auto & definedValue_4 = definedValue_2.size.Emplace();
                        definedValue_4.width = params.brandingInformation.waterMark.size.width.doubleValue;
                        definedValue_4.height = params.brandingInformation.waterMark.size.height.doubleValue;
                        definedValue_4.metric = static_cast<std::remove_reference_t<decltype(definedValue_4.metric)>>(
                            params.brandingInformation.waterMark.size.metric.unsignedCharValue);
                    }
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeAcceptHeaderWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ContentLauncher::Attributes::AcceptHeader::TypeInfo;
    return MTRReadAttribute<MTRContentLauncherAcceptHeaderListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptHeaderWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ContentLauncher::Attributes::AcceptHeader::TypeInfo;
    MTRSubscribeAttribute<MTRContentLauncherAcceptHeaderListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptHeaderWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRContentLauncherAcceptHeaderListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ContentLauncherAcceptHeaderListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ContentLauncher::Attributes::AcceptHeader::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSupportedStreamingProtocolsWithCompletion:(void (^)(
                                                                   NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ContentLauncher::Attributes::SupportedStreamingProtocols::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeSupportedStreamingProtocolsWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeSupportedStreamingProtocolsWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeSupportedStreamingProtocolsWithValue:(NSNumber * _Nonnull)value
                                                    params:(MTRWriteParams * _Nullable)params
                                                completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ContentLauncher::Attributes::SupportedStreamingProtocols::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedIntValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeSupportedStreamingProtocolsWithParams:(MTRSubscribeParams * _Nonnull)params
                                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ContentLauncher::Attributes::SupportedStreamingProtocols::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeSupportedStreamingProtocolsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                             endpoint:(NSNumber *)endpoint
                                                                queue:(dispatch_queue_t)queue
                                                           completion:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ContentLauncher::Attributes::SupportedStreamingProtocols::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ContentLauncher::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRContentLauncherGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ContentLauncher::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRContentLauncherGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRContentLauncherGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ContentLauncherGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ContentLauncher::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ContentLauncher::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRContentLauncherAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ContentLauncher::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRContentLauncherAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRContentLauncherAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ContentLauncherAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ContentLauncher::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ContentLauncher::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRContentLauncherEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ContentLauncher::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRContentLauncherEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRContentLauncherEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ContentLauncherEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ContentLauncher::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ContentLauncher::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRContentLauncherAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ContentLauncher::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRContentLauncherAttributeListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRContentLauncherAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ContentLauncherAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ContentLauncher::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ContentLauncher::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ContentLauncher::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ContentLauncher::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ContentLauncher::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ContentLauncher::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ContentLauncher::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterContentLauncher (Deprecated)

- (void)launchContentWithParams:(MTRContentLauncherClusterLaunchContentParams *)params
              completionHandler:(void (^)(MTRContentLauncherClusterLaunchResponseParams * _Nullable data,
                                    NSError * _Nullable error))completionHandler
{
    [self launchContentWithParams:params
                       completion:^(MTRContentLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error) {
                           // Cast is safe because subclass does not add any selectors.
                           completionHandler(static_cast<MTRContentLauncherClusterLaunchResponseParams *>(data), error);
                       }];
}
- (void)launchURLWithParams:(MTRContentLauncherClusterLaunchURLParams *)params
          completionHandler:
              (void (^)(MTRContentLauncherClusterLaunchResponseParams * _Nullable data, NSError * _Nullable error))completionHandler
{
    [self launchURLWithParams:params
                   completion:^(MTRContentLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error) {
                       // Cast is safe because subclass does not add any selectors.
                       completionHandler(static_cast<MTRContentLauncherClusterLaunchResponseParams *>(data), error);
                   }];
}

- (void)readAttributeAcceptHeaderWithCompletionHandler:(void (^)(
                                                           NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptHeaderWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptHeaderWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptHeaderWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSArray *>(value), error);
                                     }];
}
+ (void)readAttributeAcceptHeaderWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptHeaderWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSArray *>(value), error);
                                              }];
}

- (void)readAttributeSupportedStreamingProtocolsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))completionHandler
{
    [self readAttributeSupportedStreamingProtocolsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeSupportedStreamingProtocolsWithValue:(NSNumber * _Nonnull)value
                                         completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeSupportedStreamingProtocolsWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeSupportedStreamingProtocolsWithValue:(NSNumber * _Nonnull)value
                                                    params:(MTRWriteParams * _Nullable)params
                                         completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeSupportedStreamingProtocolsWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeSupportedStreamingProtocolsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                                              params:(MTRSubscribeParams * _Nullable)params
                                             subscriptionEstablished:
                                                 (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                       reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeSupportedStreamingProtocolsWithParams:subscribeParams
                                          subscriptionEstablished:subscriptionEstablishedHandler
                                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                        // Cast is safe because subclass does not add any selectors.
                                                        reportHandler(static_cast<NSNumber *>(value), error);
                                                    }];
}
+ (void)readAttributeSupportedStreamingProtocolsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                          endpoint:(NSNumber *)endpoint
                                                             queue:(dispatch_queue_t)queue
                                                 completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completionHandler
{
    [self readAttributeSupportedStreamingProtocolsWithClusterStateCache:attributeCacheContainer.realContainer
                                                               endpoint:endpoint
                                                                  queue:queue
                                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                 // Cast is safe because subclass does not add any selectors.
                                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                                             }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterAudioOutput

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)selectOutputWithParams:(MTRAudioOutputClusterSelectOutputParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            AudioOutput::Commands::SelectOutput::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.index = params.index.unsignedCharValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)renameOutputWithParams:(MTRAudioOutputClusterRenameOutputParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            AudioOutput::Commands::RenameOutput::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.index = params.index.unsignedCharValue;
            request.name = [self asCharSpan:params.name];

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeOutputListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = AudioOutput::Attributes::OutputList::TypeInfo;
    return MTRReadAttribute<MTRAudioOutputOutputListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeOutputListWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = AudioOutput::Attributes::OutputList::TypeInfo;
    MTRSubscribeAttribute<MTRAudioOutputOutputListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeOutputListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRAudioOutputOutputListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(AudioOutputOutputListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AudioOutput::Attributes::OutputList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCurrentOutputWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = AudioOutput::Attributes::CurrentOutput::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeCurrentOutputWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = AudioOutput::Attributes::CurrentOutput::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeCurrentOutputWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AudioOutput::Attributes::CurrentOutput::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = AudioOutput::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRAudioOutputGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = AudioOutput::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRAudioOutputGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRAudioOutputGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(AudioOutputGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AudioOutput::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = AudioOutput::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRAudioOutputAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = AudioOutput::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRAudioOutputAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRAudioOutputAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(AudioOutputAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AudioOutput::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = AudioOutput::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRAudioOutputEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = AudioOutput::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRAudioOutputEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRAudioOutputEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(AudioOutputEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AudioOutput::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = AudioOutput::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRAudioOutputAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = AudioOutput::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRAudioOutputAttributeListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRAudioOutputAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(AudioOutputAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AudioOutput::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = AudioOutput::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = AudioOutput::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AudioOutput::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = AudioOutput::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = AudioOutput::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AudioOutput::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterAudioOutput (Deprecated)

- (void)selectOutputWithParams:(MTRAudioOutputClusterSelectOutputParams *)params
             completionHandler:(MTRStatusCompletion)completionHandler
{
    [self selectOutputWithParams:params completion:completionHandler];
}
- (void)renameOutputWithParams:(MTRAudioOutputClusterRenameOutputParams *)params
             completionHandler:(MTRStatusCompletion)completionHandler
{
    [self renameOutputWithParams:params completion:completionHandler];
}

- (void)readAttributeOutputListWithCompletionHandler:(void (^)(
                                                         NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOutputListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeOutputListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeOutputListWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSArray *>(value), error);
                                   }];
}
+ (void)readAttributeOutputListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOutputListWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSArray *>(value), error);
                                            }];
}

- (void)readAttributeCurrentOutputWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentOutputWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeCurrentOutputWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeCurrentOutputWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributeCurrentOutputWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentOutputWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterApplicationLauncher

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)launchAppWithParams:(MTRApplicationLauncherClusterLaunchAppParams * _Nullable)params
                 completion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data,
                                NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRApplicationLauncherClusterLauncherResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            ApplicationLauncherClusterLauncherResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRApplicationLauncherClusterLauncherResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            ApplicationLauncher::Commands::LaunchApp::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            if (params != nil) {
                if (params.application != nil) {
                    auto & definedValue_0 = request.application.Emplace();
                    definedValue_0.catalogVendorID = params.application.catalogVendorID.unsignedShortValue;
                    definedValue_0.applicationID = [self asCharSpan:params.application.applicationID];
                }
                if (params.data != nil) {
                    auto & definedValue_0 = request.data.Emplace();
                    definedValue_0 = [self asByteSpan:params.data];
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)stopAppWithParams:(MTRApplicationLauncherClusterStopAppParams * _Nullable)params
               completion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data,
                              NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRApplicationLauncherClusterLauncherResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            ApplicationLauncherClusterLauncherResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRApplicationLauncherClusterLauncherResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            ApplicationLauncher::Commands::StopApp::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            if (params != nil) {
                if (params.application != nil) {
                    auto & definedValue_0 = request.application.Emplace();
                    definedValue_0.catalogVendorID = params.application.catalogVendorID.unsignedShortValue;
                    definedValue_0.applicationID = [self asCharSpan:params.application.applicationID];
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)hideAppWithParams:(MTRApplicationLauncherClusterHideAppParams * _Nullable)params
               completion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data,
                              NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRApplicationLauncherClusterLauncherResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            ApplicationLauncherClusterLauncherResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRApplicationLauncherClusterLauncherResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            ApplicationLauncher::Commands::HideApp::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            if (params != nil) {
                if (params.application != nil) {
                    auto & definedValue_0 = request.application.Emplace();
                    definedValue_0.catalogVendorID = params.application.catalogVendorID.unsignedShortValue;
                    definedValue_0.applicationID = [self asCharSpan:params.application.applicationID];
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeCatalogListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ApplicationLauncher::Attributes::CatalogList::TypeInfo;
    return MTRReadAttribute<MTRApplicationLauncherCatalogListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeCatalogListWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ApplicationLauncher::Attributes::CatalogList::TypeInfo;
    MTRSubscribeAttribute<MTRApplicationLauncherCatalogListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeCatalogListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRApplicationLauncherCatalogListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ApplicationLauncherCatalogListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ApplicationLauncher::Attributes::CatalogList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCurrentAppWithCompletion:(void (^)(MTRApplicationLauncherClusterApplicationEPStruct * _Nullable value,
                                                  NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ApplicationLauncher::Attributes::CurrentApp::TypeInfo;
    return MTRReadAttribute<MTRApplicationLauncherCurrentAppStructAttributeCallbackBridge,
        MTRApplicationLauncherClusterApplicationEPStruct, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeCurrentAppWithValue:(MTRApplicationLauncherClusterApplicationEPStruct * _Nullable)value
                               completion:(MTRStatusCompletion)completion
{
    [self writeAttributeCurrentAppWithValue:(MTRApplicationLauncherClusterApplicationEPStruct * _Nullable) value
                                     params:nil
                                 completion:completion];
}
- (void)writeAttributeCurrentAppWithValue:(MTRApplicationLauncherClusterApplicationEPStruct * _Nullable)value
                                   params:(MTRWriteParams * _Nullable)params
                               completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ApplicationLauncher::Attributes::CurrentApp::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0.application.catalogVendorID = value.application.catalogVendorID.unsignedShortValue;
                nonNullValue_0.application.applicationID = [self asCharSpan:value.application.applicationID];
                if (value.endpoint != nil) {
                    auto & definedValue_2 = nonNullValue_0.endpoint.Emplace();
                    definedValue_2 = value.endpoint.unsignedShortValue;
                }
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeCurrentAppWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(MTRApplicationLauncherClusterApplicationEPStruct * _Nullable value,
                                                   NSError * _Nullable error))reportHandler
{
    using TypeInfo = ApplicationLauncher::Attributes::CurrentApp::TypeInfo;
    MTRSubscribeAttribute<MTRApplicationLauncherCurrentAppStructAttributeCallbackSubscriptionBridge,
        MTRApplicationLauncherClusterApplicationEPStruct, TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler,
        self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeCurrentAppWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(MTRApplicationLauncherClusterApplicationEPStruct * _Nullable value,
                                                         NSError * _Nullable error))completion
{
    auto * bridge = new MTRApplicationLauncherCurrentAppStructAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ApplicationLauncherCurrentAppStructAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ApplicationLauncher::Attributes::CurrentApp::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ApplicationLauncher::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRApplicationLauncherGeneratedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ApplicationLauncher::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRApplicationLauncherGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRApplicationLauncherGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ApplicationLauncherGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ApplicationLauncher::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ApplicationLauncher::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRApplicationLauncherAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ApplicationLauncher::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRApplicationLauncherAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRApplicationLauncherAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ApplicationLauncherAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ApplicationLauncher::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ApplicationLauncher::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRApplicationLauncherEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ApplicationLauncher::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRApplicationLauncherEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRApplicationLauncherEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ApplicationLauncherEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ApplicationLauncher::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ApplicationLauncher::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRApplicationLauncherAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ApplicationLauncher::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRApplicationLauncherAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRApplicationLauncherAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ApplicationLauncherAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ApplicationLauncher::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ApplicationLauncher::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ApplicationLauncher::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ApplicationLauncher::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ApplicationLauncher::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ApplicationLauncher::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ApplicationLauncher::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterApplicationLauncher (Deprecated)

- (void)launchAppWithParams:(MTRApplicationLauncherClusterLaunchAppParams * _Nullable)params
          completionHandler:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data,
                                NSError * _Nullable error))completionHandler
{
    [self launchAppWithParams:params
                   completion:^(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error) {
                       // Cast is safe because subclass does not add any selectors.
                       completionHandler(static_cast<MTRApplicationLauncherClusterLauncherResponseParams *>(data), error);
                   }];
}
- (void)stopAppWithParams:(MTRApplicationLauncherClusterStopAppParams * _Nullable)params
        completionHandler:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data,
                              NSError * _Nullable error))completionHandler
{
    [self stopAppWithParams:params
                 completion:^(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error) {
                     // Cast is safe because subclass does not add any selectors.
                     completionHandler(static_cast<MTRApplicationLauncherClusterLauncherResponseParams *>(data), error);
                 }];
}
- (void)hideAppWithParams:(MTRApplicationLauncherClusterHideAppParams * _Nullable)params
        completionHandler:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data,
                              NSError * _Nullable error))completionHandler
{
    [self hideAppWithParams:params
                 completion:^(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error) {
                     // Cast is safe because subclass does not add any selectors.
                     completionHandler(static_cast<MTRApplicationLauncherClusterLauncherResponseParams *>(data), error);
                 }];
}

- (void)readAttributeCatalogListWithCompletionHandler:(void (^)(
                                                          NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCatalogListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeCatalogListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeCatalogListWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSArray *>(value), error);
                                    }];
}
+ (void)readAttributeCatalogListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCatalogListWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSArray *>(value), error);
                                             }];
}

- (void)readAttributeCurrentAppWithCompletionHandler:(void (^)(MTRApplicationLauncherClusterApplicationEP * _Nullable value,
                                                         NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentAppWithCompletion:^(
        MTRApplicationLauncherClusterApplicationEPStruct * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<MTRApplicationLauncherClusterApplicationEP *>(value), error);
    }];
}
- (void)writeAttributeCurrentAppWithValue:(MTRApplicationLauncherClusterApplicationEP * _Nullable)value
                        completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeCurrentAppWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeCurrentAppWithValue:(MTRApplicationLauncherClusterApplicationEP * _Nullable)value
                                   params:(MTRWriteParams * _Nullable)params
                        completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeCurrentAppWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeCurrentAppWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(MTRApplicationLauncherClusterApplicationEP * _Nullable value,
                                                        NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeCurrentAppWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(MTRApplicationLauncherClusterApplicationEPStruct * _Nullable value,
                                       NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<MTRApplicationLauncherClusterApplicationEP *>(value), error);
                                   }];
}
+ (void)readAttributeCurrentAppWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(MTRApplicationLauncherClusterApplicationEP * _Nullable value,
                                                      NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentAppWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(MTRApplicationLauncherClusterApplicationEPStruct * _Nullable value,
                                                NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(
                                                    static_cast<MTRApplicationLauncherClusterApplicationEP *>(value), error);
                                            }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterApplicationBasic

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)readAttributeVendorNameWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ApplicationBasic::Attributes::VendorName::TypeInfo;
    return MTRReadAttribute<MTRCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeVendorNameWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ApplicationBasic::Attributes::VendorName::TypeInfo;
    MTRSubscribeAttribute<MTRCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeVendorNameWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(CharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ApplicationBasic::Attributes::VendorName::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeVendorIDWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ApplicationBasic::Attributes::VendorID::TypeInfo;
    return MTRReadAttribute<MTRVendorIdAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeVendorIDWithParams:(MTRSubscribeParams * _Nonnull)params
                     subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                               reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ApplicationBasic::Attributes::VendorID::TypeInfo;
    MTRSubscribeAttribute<MTRVendorIdAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeVendorIDWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                        completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRVendorIdAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(VendorIdAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ApplicationBasic::Attributes::VendorID::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeApplicationNameWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ApplicationBasic::Attributes::ApplicationName::TypeInfo;
    return MTRReadAttribute<MTRCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeApplicationNameWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ApplicationBasic::Attributes::ApplicationName::TypeInfo;
    MTRSubscribeAttribute<MTRCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeApplicationNameWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(CharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ApplicationBasic::Attributes::ApplicationName::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeProductIDWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ApplicationBasic::Attributes::ProductID::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeProductIDWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ApplicationBasic::Attributes::ProductID::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeProductIDWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ApplicationBasic::Attributes::ProductID::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeApplicationWithCompletion:(void (^)(MTRApplicationBasicClusterApplicationStruct * _Nullable value,
                                                   NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ApplicationBasic::Attributes::Application::TypeInfo;
    return MTRReadAttribute<MTRApplicationBasicApplicationStructAttributeCallbackBridge,
        MTRApplicationBasicClusterApplicationStruct, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeApplicationWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(MTRApplicationBasicClusterApplicationStruct * _Nullable value,
                                                    NSError * _Nullable error))reportHandler
{
    using TypeInfo = ApplicationBasic::Attributes::Application::TypeInfo;
    MTRSubscribeAttribute<MTRApplicationBasicApplicationStructAttributeCallbackSubscriptionBridge,
        MTRApplicationBasicClusterApplicationStruct, TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler,
        self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeApplicationWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(MTRApplicationBasicClusterApplicationStruct * _Nullable value,
                                                          NSError * _Nullable error))completion
{
    auto * bridge = new MTRApplicationBasicApplicationStructAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ApplicationBasicApplicationStructAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ApplicationBasic::Attributes::Application::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeStatusWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ApplicationBasic::Attributes::Status::TypeInfo;
    return MTRReadAttribute<MTRApplicationBasicClusterApplicationStatusEnumAttributeCallbackBridge, NSNumber,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeStatusWithParams:(MTRSubscribeParams * _Nonnull)params
                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                             reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ApplicationBasic::Attributes::Status::TypeInfo;
    MTRSubscribeAttribute<MTRApplicationBasicClusterApplicationStatusEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeStatusWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                                      completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRApplicationBasicClusterApplicationStatusEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ApplicationBasicClusterApplicationStatusEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ApplicationBasic::Attributes::Status::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeApplicationVersionWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ApplicationBasic::Attributes::ApplicationVersion::TypeInfo;
    return MTRReadAttribute<MTRCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeApplicationVersionWithParams:(MTRSubscribeParams * _Nonnull)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                         reportHandler:
                                             (void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ApplicationBasic::Attributes::ApplicationVersion::TypeInfo;
    MTRSubscribeAttribute<MTRCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeApplicationVersionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                                  completion:
                                                      (void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(CharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ApplicationBasic::Attributes::ApplicationVersion::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAllowedVendorListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ApplicationBasic::Attributes::AllowedVendorList::TypeInfo;
    return MTRReadAttribute<MTRApplicationBasicAllowedVendorListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAllowedVendorListWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ApplicationBasic::Attributes::AllowedVendorList::TypeInfo;
    MTRSubscribeAttribute<MTRApplicationBasicAllowedVendorListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAllowedVendorListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRApplicationBasicAllowedVendorListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ApplicationBasicAllowedVendorListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ApplicationBasic::Attributes::AllowedVendorList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ApplicationBasic::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRApplicationBasicGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ApplicationBasic::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRApplicationBasicGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRApplicationBasicGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ApplicationBasicGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ApplicationBasic::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ApplicationBasic::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRApplicationBasicAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ApplicationBasic::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRApplicationBasicAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRApplicationBasicAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ApplicationBasicAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ApplicationBasic::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ApplicationBasic::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRApplicationBasicEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ApplicationBasic::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRApplicationBasicEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRApplicationBasicEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ApplicationBasicEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ApplicationBasic::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ApplicationBasic::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRApplicationBasicAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ApplicationBasic::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRApplicationBasicAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRApplicationBasicAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ApplicationBasicAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ApplicationBasic::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ApplicationBasic::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ApplicationBasic::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ApplicationBasic::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ApplicationBasic::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ApplicationBasic::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ApplicationBasic::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterApplicationBasic (Deprecated)

- (void)readAttributeVendorNameWithCompletionHandler:(void (^)(
                                                         NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeVendorNameWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)subscribeAttributeVendorNameWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeVendorNameWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSString *>(value), error);
                                   }];
}
+ (void)readAttributeVendorNameWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeVendorNameWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSString *>(value), error);
                                            }];
}

- (void)readAttributeVendorIDWithCompletionHandler:(void (^)(
                                                       NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeVendorIDWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeVendorIDWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeVendorIDWithParams:subscribeParams
                       subscriptionEstablished:subscriptionEstablishedHandler
                                 reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                     // Cast is safe because subclass does not add any selectors.
                                     reportHandler(static_cast<NSNumber *>(value), error);
                                 }];
}
+ (void)readAttributeVendorIDWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeVendorIDWithClusterStateCache:attributeCacheContainer.realContainer
                                            endpoint:endpoint
                                               queue:queue
                                          completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              completionHandler(static_cast<NSNumber *>(value), error);
                                          }];
}

- (void)readAttributeApplicationNameWithCompletionHandler:(void (^)(NSString * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeApplicationNameWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)subscribeAttributeApplicationNameWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeApplicationNameWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSString *>(value), error);
                                        }];
}
+ (void)readAttributeApplicationNameWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeApplicationNameWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSString *>(value), error);
                                                 }];
}

- (void)readAttributeProductIDWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeProductIDWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeProductIDWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeProductIDWithParams:subscribeParams
                        subscriptionEstablished:subscriptionEstablishedHandler
                                  reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                      // Cast is safe because subclass does not add any selectors.
                                      reportHandler(static_cast<NSNumber *>(value), error);
                                  }];
}
+ (void)readAttributeProductIDWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeProductIDWithClusterStateCache:attributeCacheContainer.realContainer
                                             endpoint:endpoint
                                                queue:queue
                                           completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               completionHandler(static_cast<NSNumber *>(value), error);
                                           }];
}

- (void)readAttributeApplicationWithCompletionHandler:
    (void (^)(MTRApplicationBasicClusterApplicationBasicApplication * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeApplicationWithCompletion:^(
        MTRApplicationBasicClusterApplicationStruct * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<MTRApplicationBasicClusterApplicationBasicApplication *>(value), error);
    }];
}
- (void)subscribeAttributeApplicationWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:
                                           (void (^)(MTRApplicationBasicClusterApplicationBasicApplication * _Nullable value,
                                               NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeApplicationWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(
                                        MTRApplicationBasicClusterApplicationStruct * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(
                                            static_cast<MTRApplicationBasicClusterApplicationBasicApplication *>(value), error);
                                    }];
}
+ (void)readAttributeApplicationWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(MTRApplicationBasicClusterApplicationBasicApplication * _Nullable value,
                                         NSError * _Nullable error))completionHandler
{
    [self readAttributeApplicationWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(MTRApplicationBasicClusterApplicationStruct * _Nullable value,
                                                 NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(
                                                     static_cast<MTRApplicationBasicClusterApplicationBasicApplication *>(value),
                                                     error);
                                             }];
}

- (void)readAttributeStatusWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeStatusWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeStatusWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeStatusWithParams:subscribeParams
                     subscriptionEstablished:subscriptionEstablishedHandler
                               reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                   // Cast is safe because subclass does not add any selectors.
                                   reportHandler(static_cast<NSNumber *>(value), error);
                               }];
}
+ (void)readAttributeStatusWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeStatusWithClusterStateCache:attributeCacheContainer.realContainer
                                          endpoint:endpoint
                                             queue:queue
                                        completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            completionHandler(static_cast<NSNumber *>(value), error);
                                        }];
}

- (void)readAttributeApplicationVersionWithCompletionHandler:(void (^)(NSString * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    [self readAttributeApplicationVersionWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)subscribeAttributeApplicationVersionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:
                                        (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeApplicationVersionWithParams:subscribeParams
                                 subscriptionEstablished:subscriptionEstablishedHandler
                                           reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               reportHandler(static_cast<NSString *>(value), error);
                                           }];
}
+ (void)readAttributeApplicationVersionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeApplicationVersionWithClusterStateCache:attributeCacheContainer.realContainer
                                                      endpoint:endpoint
                                                         queue:queue
                                                    completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                                        // Cast is safe because subclass does not add any selectors.
                                                        completionHandler(static_cast<NSString *>(value), error);
                                                    }];
}

- (void)readAttributeAllowedVendorListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeAllowedVendorListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)
    subscribeAttributeAllowedVendorListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAllowedVendorListWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSArray *>(value), error);
                                          }];
}
+ (void)readAttributeAllowedVendorListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAllowedVendorListWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSArray *>(value), error);
                                                   }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterAccountLogin

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)getSetupPINWithParams:(MTRAccountLoginClusterGetSetupPINParams *)params
                   completion:(void (^)(MTRAccountLoginClusterGetSetupPINResponseParams * _Nullable data,
                                  NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRAccountLoginClusterGetSetupPINResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            AccountLoginClusterGetSetupPINResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRAccountLoginClusterGetSetupPINResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            AccountLogin::Commands::GetSetupPIN::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            if (!timedInvokeTimeoutMs.HasValue()) {
                timedInvokeTimeoutMs.SetValue(10000);
            }
            request.tempAccountIdentifier = [self asCharSpan:params.tempAccountIdentifier];

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)loginWithParams:(MTRAccountLoginClusterLoginParams *)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            AccountLogin::Commands::Login::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            if (!timedInvokeTimeoutMs.HasValue()) {
                timedInvokeTimeoutMs.SetValue(10000);
            }
            request.tempAccountIdentifier = [self asCharSpan:params.tempAccountIdentifier];
            request.setupPIN = [self asCharSpan:params.setupPIN];

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)logoutWithCompletion:(MTRStatusCompletion)completion
{
    [self logoutWithParams:nil completion:completion];
}
- (void)logoutWithParams:(MTRAccountLoginClusterLogoutParams * _Nullable)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            AccountLogin::Commands::Logout::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            if (!timedInvokeTimeoutMs.HasValue()) {
                timedInvokeTimeoutMs.SetValue(10000);
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = AccountLogin::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRAccountLoginGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = AccountLogin::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRAccountLoginGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRAccountLoginGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(AccountLoginGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AccountLogin::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = AccountLogin::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRAccountLoginAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = AccountLogin::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRAccountLoginAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRAccountLoginAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(AccountLoginAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AccountLogin::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = AccountLogin::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRAccountLoginEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = AccountLogin::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRAccountLoginEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRAccountLoginEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(AccountLoginEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AccountLogin::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = AccountLogin::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRAccountLoginAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = AccountLogin::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRAccountLoginAttributeListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRAccountLoginAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(AccountLoginAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AccountLogin::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = AccountLogin::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = AccountLogin::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AccountLogin::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = AccountLogin::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = AccountLogin::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AccountLogin::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterAccountLogin (Deprecated)

- (void)getSetupPINWithParams:(MTRAccountLoginClusterGetSetupPINParams *)params
            completionHandler:(void (^)(MTRAccountLoginClusterGetSetupPINResponseParams * _Nullable data,
                                  NSError * _Nullable error))completionHandler
{
    [self getSetupPINWithParams:params
                     completion:^(MTRAccountLoginClusterGetSetupPINResponseParams * _Nullable data, NSError * _Nullable error) {
                         // Cast is safe because subclass does not add any selectors.
                         completionHandler(static_cast<MTRAccountLoginClusterGetSetupPINResponseParams *>(data), error);
                     }];
}
- (void)loginWithParams:(MTRAccountLoginClusterLoginParams *)params completionHandler:(MTRStatusCompletion)completionHandler
{
    [self loginWithParams:params completion:completionHandler];
}
- (void)logoutWithParams:(MTRAccountLoginClusterLogoutParams * _Nullable)params
       completionHandler:(MTRStatusCompletion)completionHandler
{
    [self logoutWithParams:params completion:completionHandler];
}
- (void)logoutWithCompletionHandler:(MTRStatusCompletion)completionHandler
{
    [self logoutWithParams:nil completionHandler:completionHandler];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterElectricalMeasurement

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)getProfileInfoCommandWithCompletion:(MTRStatusCompletion)completion
{
    [self getProfileInfoCommandWithParams:nil completion:completion];
}
- (void)getProfileInfoCommandWithParams:(MTRElectricalMeasurementClusterGetProfileInfoCommandParams * _Nullable)params
                             completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            ElectricalMeasurement::Commands::GetProfileInfoCommand::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)getMeasurementProfileCommandWithParams:(MTRElectricalMeasurementClusterGetMeasurementProfileCommandParams *)params
                                    completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            ElectricalMeasurement::Commands::GetMeasurementProfileCommand::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.attributeId = params.attributeId.unsignedShortValue;
            request.startTime = params.startTime.unsignedIntValue;
            request.numberOfIntervals = params.numberOfIntervals.unsignedCharValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeMeasurementTypeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::MeasurementType::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMeasurementTypeWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::MeasurementType::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMeasurementTypeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::MeasurementType::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeDcVoltageWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::DcVoltage::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeDcVoltageWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::DcVoltage::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeDcVoltageWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::DcVoltage::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeDcVoltageMinWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::DcVoltageMin::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeDcVoltageMinWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::DcVoltageMin::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeDcVoltageMinWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::DcVoltageMin::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeDcVoltageMaxWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::DcVoltageMax::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeDcVoltageMaxWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::DcVoltageMax::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeDcVoltageMaxWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::DcVoltageMax::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeDcCurrentWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::DcCurrent::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeDcCurrentWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::DcCurrent::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeDcCurrentWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::DcCurrent::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeDcCurrentMinWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::DcCurrentMin::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeDcCurrentMinWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::DcCurrentMin::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeDcCurrentMinWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::DcCurrentMin::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeDcCurrentMaxWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::DcCurrentMax::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeDcCurrentMaxWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::DcCurrentMax::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeDcCurrentMaxWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::DcCurrentMax::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeDcPowerWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::DcPower::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeDcPowerWithParams:(MTRSubscribeParams * _Nonnull)params
                    subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                              reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::DcPower::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeDcPowerWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                       completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::DcPower::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeDcPowerMinWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::DcPowerMin::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeDcPowerMinWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::DcPowerMin::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeDcPowerMinWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::DcPowerMin::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeDcPowerMaxWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::DcPowerMax::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeDcPowerMaxWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::DcPowerMax::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeDcPowerMaxWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::DcPowerMax::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeDcVoltageMultiplierWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::DcVoltageMultiplier::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeDcVoltageMultiplierWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::DcVoltageMultiplier::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeDcVoltageMultiplierWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::DcVoltageMultiplier::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeDcVoltageDivisorWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::DcVoltageDivisor::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeDcVoltageDivisorWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::DcVoltageDivisor::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeDcVoltageDivisorWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::DcVoltageDivisor::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeDcCurrentMultiplierWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::DcCurrentMultiplier::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeDcCurrentMultiplierWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::DcCurrentMultiplier::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeDcCurrentMultiplierWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::DcCurrentMultiplier::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeDcCurrentDivisorWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::DcCurrentDivisor::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeDcCurrentDivisorWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::DcCurrentDivisor::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeDcCurrentDivisorWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::DcCurrentDivisor::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeDcPowerMultiplierWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::DcPowerMultiplier::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeDcPowerMultiplierWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::DcPowerMultiplier::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeDcPowerMultiplierWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::DcPowerMultiplier::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeDcPowerDivisorWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::DcPowerDivisor::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeDcPowerDivisorWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::DcPowerDivisor::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeDcPowerDivisorWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::DcPowerDivisor::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcFrequencyWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::AcFrequency::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcFrequencyWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::AcFrequency::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcFrequencyWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::AcFrequency::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcFrequencyMinWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::AcFrequencyMin::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcFrequencyMinWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::AcFrequencyMin::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcFrequencyMinWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::AcFrequencyMin::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcFrequencyMaxWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::AcFrequencyMax::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcFrequencyMaxWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::AcFrequencyMax::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcFrequencyMaxWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::AcFrequencyMax::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNeutralCurrentWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::NeutralCurrent::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeNeutralCurrentWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::NeutralCurrent::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNeutralCurrentWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::NeutralCurrent::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeTotalActivePowerWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::TotalActivePower::TypeInfo;
    return MTRReadAttribute<MTRInt32sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeTotalActivePowerWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::TotalActivePower::TypeInfo;
    MTRSubscribeAttribute<MTRInt32sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeTotalActivePowerWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::TotalActivePower::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeTotalReactivePowerWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::TotalReactivePower::TypeInfo;
    return MTRReadAttribute<MTRInt32sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeTotalReactivePowerWithParams:(MTRSubscribeParams * _Nonnull)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::TotalReactivePower::TypeInfo;
    MTRSubscribeAttribute<MTRInt32sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeTotalReactivePowerWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                                  completion:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::TotalReactivePower::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeTotalApparentPowerWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::TotalApparentPower::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeTotalApparentPowerWithParams:(MTRSubscribeParams * _Nonnull)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::TotalApparentPower::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeTotalApparentPowerWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                                  completion:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::TotalApparentPower::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMeasured1stHarmonicCurrentWithCompletion:(void (^)(
                                                                  NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::Measured1stHarmonicCurrent::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMeasured1stHarmonicCurrentWithParams:(MTRSubscribeParams * _Nonnull)params
                                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::Measured1stHarmonicCurrent::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMeasured1stHarmonicCurrentWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                            endpoint:(NSNumber *)endpoint
                                                               queue:(dispatch_queue_t)queue
                                                          completion:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::Measured1stHarmonicCurrent::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMeasured3rdHarmonicCurrentWithCompletion:(void (^)(
                                                                  NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::Measured3rdHarmonicCurrent::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMeasured3rdHarmonicCurrentWithParams:(MTRSubscribeParams * _Nonnull)params
                                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::Measured3rdHarmonicCurrent::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMeasured3rdHarmonicCurrentWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                            endpoint:(NSNumber *)endpoint
                                                               queue:(dispatch_queue_t)queue
                                                          completion:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::Measured3rdHarmonicCurrent::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMeasured5thHarmonicCurrentWithCompletion:(void (^)(
                                                                  NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::Measured5thHarmonicCurrent::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMeasured5thHarmonicCurrentWithParams:(MTRSubscribeParams * _Nonnull)params
                                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::Measured5thHarmonicCurrent::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMeasured5thHarmonicCurrentWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                            endpoint:(NSNumber *)endpoint
                                                               queue:(dispatch_queue_t)queue
                                                          completion:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::Measured5thHarmonicCurrent::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMeasured7thHarmonicCurrentWithCompletion:(void (^)(
                                                                  NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::Measured7thHarmonicCurrent::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMeasured7thHarmonicCurrentWithParams:(MTRSubscribeParams * _Nonnull)params
                                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::Measured7thHarmonicCurrent::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMeasured7thHarmonicCurrentWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                            endpoint:(NSNumber *)endpoint
                                                               queue:(dispatch_queue_t)queue
                                                          completion:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::Measured7thHarmonicCurrent::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMeasured9thHarmonicCurrentWithCompletion:(void (^)(
                                                                  NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::Measured9thHarmonicCurrent::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMeasured9thHarmonicCurrentWithParams:(MTRSubscribeParams * _Nonnull)params
                                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::Measured9thHarmonicCurrent::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMeasured9thHarmonicCurrentWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                            endpoint:(NSNumber *)endpoint
                                                               queue:(dispatch_queue_t)queue
                                                          completion:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::Measured9thHarmonicCurrent::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMeasured11thHarmonicCurrentWithCompletion:(void (^)(
                                                                   NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::Measured11thHarmonicCurrent::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMeasured11thHarmonicCurrentWithParams:(MTRSubscribeParams * _Nonnull)params
                                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::Measured11thHarmonicCurrent::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMeasured11thHarmonicCurrentWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                             endpoint:(NSNumber *)endpoint
                                                                queue:(dispatch_queue_t)queue
                                                           completion:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::Measured11thHarmonicCurrent::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMeasuredPhase1stHarmonicCurrentWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::MeasuredPhase1stHarmonicCurrent::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMeasuredPhase1stHarmonicCurrentWithParams:(MTRSubscribeParams * _Nonnull)params
                                            subscriptionEstablished:
                                                (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                      reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::MeasuredPhase1stHarmonicCurrent::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMeasuredPhase1stHarmonicCurrentWithClusterStateCache:
            (MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                                 endpoint:(NSNumber *)endpoint
                                                                    queue:(dispatch_queue_t)queue
                                                               completion:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::MeasuredPhase1stHarmonicCurrent::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMeasuredPhase3rdHarmonicCurrentWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::MeasuredPhase3rdHarmonicCurrent::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMeasuredPhase3rdHarmonicCurrentWithParams:(MTRSubscribeParams * _Nonnull)params
                                            subscriptionEstablished:
                                                (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                      reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::MeasuredPhase3rdHarmonicCurrent::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMeasuredPhase3rdHarmonicCurrentWithClusterStateCache:
            (MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                                 endpoint:(NSNumber *)endpoint
                                                                    queue:(dispatch_queue_t)queue
                                                               completion:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::MeasuredPhase3rdHarmonicCurrent::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMeasuredPhase5thHarmonicCurrentWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::MeasuredPhase5thHarmonicCurrent::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMeasuredPhase5thHarmonicCurrentWithParams:(MTRSubscribeParams * _Nonnull)params
                                            subscriptionEstablished:
                                                (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                      reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::MeasuredPhase5thHarmonicCurrent::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMeasuredPhase5thHarmonicCurrentWithClusterStateCache:
            (MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                                 endpoint:(NSNumber *)endpoint
                                                                    queue:(dispatch_queue_t)queue
                                                               completion:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::MeasuredPhase5thHarmonicCurrent::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMeasuredPhase7thHarmonicCurrentWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::MeasuredPhase7thHarmonicCurrent::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMeasuredPhase7thHarmonicCurrentWithParams:(MTRSubscribeParams * _Nonnull)params
                                            subscriptionEstablished:
                                                (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                      reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::MeasuredPhase7thHarmonicCurrent::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMeasuredPhase7thHarmonicCurrentWithClusterStateCache:
            (MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                                 endpoint:(NSNumber *)endpoint
                                                                    queue:(dispatch_queue_t)queue
                                                               completion:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::MeasuredPhase7thHarmonicCurrent::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMeasuredPhase9thHarmonicCurrentWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::MeasuredPhase9thHarmonicCurrent::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMeasuredPhase9thHarmonicCurrentWithParams:(MTRSubscribeParams * _Nonnull)params
                                            subscriptionEstablished:
                                                (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                      reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::MeasuredPhase9thHarmonicCurrent::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMeasuredPhase9thHarmonicCurrentWithClusterStateCache:
            (MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                                 endpoint:(NSNumber *)endpoint
                                                                    queue:(dispatch_queue_t)queue
                                                               completion:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::MeasuredPhase9thHarmonicCurrent::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMeasuredPhase11thHarmonicCurrentWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::MeasuredPhase11thHarmonicCurrent::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeMeasuredPhase11thHarmonicCurrentWithParams:(MTRSubscribeParams * _Nonnull)params
                                             subscriptionEstablished:
                                                 (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                       reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::MeasuredPhase11thHarmonicCurrent::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeMeasuredPhase11thHarmonicCurrentWithClusterStateCache:
            (MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                                  endpoint:(NSNumber *)endpoint
                                                                     queue:(dispatch_queue_t)queue
                                                                completion:(void (^)(NSNumber * _Nullable value,
                                                                               NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::MeasuredPhase11thHarmonicCurrent::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcFrequencyMultiplierWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::AcFrequencyMultiplier::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcFrequencyMultiplierWithParams:(MTRSubscribeParams * _Nonnull)params
                                  subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::AcFrequencyMultiplier::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcFrequencyMultiplierWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                                     completion:
                                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::AcFrequencyMultiplier::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcFrequencyDivisorWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::AcFrequencyDivisor::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcFrequencyDivisorWithParams:(MTRSubscribeParams * _Nonnull)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::AcFrequencyDivisor::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcFrequencyDivisorWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                                  completion:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::AcFrequencyDivisor::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePowerMultiplierWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::PowerMultiplier::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePowerMultiplierWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::PowerMultiplier::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePowerMultiplierWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::PowerMultiplier::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePowerDivisorWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::PowerDivisor::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePowerDivisorWithParams:(MTRSubscribeParams * _Nonnull)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::PowerDivisor::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePowerDivisorWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                            completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::PowerDivisor::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeHarmonicCurrentMultiplierWithCompletion:(void (^)(
                                                                 NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::HarmonicCurrentMultiplier::TypeInfo;
    return MTRReadAttribute<MTRInt8sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeHarmonicCurrentMultiplierWithParams:(MTRSubscribeParams * _Nonnull)params
                                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::HarmonicCurrentMultiplier::TypeInfo;
    MTRSubscribeAttribute<MTRInt8sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeHarmonicCurrentMultiplierWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                           endpoint:(NSNumber *)endpoint
                                                              queue:(dispatch_queue_t)queue
                                                         completion:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::HarmonicCurrentMultiplier::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePhaseHarmonicCurrentMultiplierWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::PhaseHarmonicCurrentMultiplier::TypeInfo;
    return MTRReadAttribute<MTRInt8sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePhaseHarmonicCurrentMultiplierWithParams:(MTRSubscribeParams * _Nonnull)params
                                           subscriptionEstablished:
                                               (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                     reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::PhaseHarmonicCurrentMultiplier::TypeInfo;
    MTRSubscribeAttribute<MTRInt8sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePhaseHarmonicCurrentMultiplierWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                                endpoint:(NSNumber *)endpoint
                                                                   queue:(dispatch_queue_t)queue
                                                              completion:(void (^)(NSNumber * _Nullable value,
                                                                             NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::PhaseHarmonicCurrentMultiplier::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeInstantaneousVoltageWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::InstantaneousVoltage::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeInstantaneousVoltageWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::InstantaneousVoltage::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeInstantaneousVoltageWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::InstantaneousVoltage::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeInstantaneousLineCurrentWithCompletion:(void (^)(
                                                                NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::InstantaneousLineCurrent::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeInstantaneousLineCurrentWithParams:(MTRSubscribeParams * _Nonnull)params
                                     subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::InstantaneousLineCurrent::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeInstantaneousLineCurrentWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                          endpoint:(NSNumber *)endpoint
                                                             queue:(dispatch_queue_t)queue
                                                        completion:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::InstantaneousLineCurrent::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeInstantaneousActiveCurrentWithCompletion:(void (^)(
                                                                  NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::InstantaneousActiveCurrent::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeInstantaneousActiveCurrentWithParams:(MTRSubscribeParams * _Nonnull)params
                                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::InstantaneousActiveCurrent::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeInstantaneousActiveCurrentWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                            endpoint:(NSNumber *)endpoint
                                                               queue:(dispatch_queue_t)queue
                                                          completion:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::InstantaneousActiveCurrent::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeInstantaneousReactiveCurrentWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::InstantaneousReactiveCurrent::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeInstantaneousReactiveCurrentWithParams:(MTRSubscribeParams * _Nonnull)params
                                         subscriptionEstablished:
                                             (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                   reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::InstantaneousReactiveCurrent::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeInstantaneousReactiveCurrentWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                              endpoint:(NSNumber *)endpoint
                                                                 queue:(dispatch_queue_t)queue
                                                            completion:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::InstantaneousReactiveCurrent::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeInstantaneousPowerWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::InstantaneousPower::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeInstantaneousPowerWithParams:(MTRSubscribeParams * _Nonnull)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::InstantaneousPower::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeInstantaneousPowerWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                                  completion:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::InstantaneousPower::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRmsVoltageWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltage::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRmsVoltageWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltage::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRmsVoltageWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltage::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRmsVoltageMinWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageMin::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRmsVoltageMinWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageMin::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRmsVoltageMinWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageMin::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRmsVoltageMaxWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageMax::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRmsVoltageMaxWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageMax::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRmsVoltageMaxWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageMax::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRmsCurrentWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrent::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRmsCurrentWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrent::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRmsCurrentWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrent::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRmsCurrentMinWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentMin::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRmsCurrentMinWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentMin::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRmsCurrentMinWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentMin::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRmsCurrentMaxWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentMax::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRmsCurrentMaxWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentMax::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRmsCurrentMaxWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentMax::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeActivePowerWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::ActivePower::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeActivePowerWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::ActivePower::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeActivePowerWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::ActivePower::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeActivePowerMinWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerMin::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeActivePowerMinWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerMin::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeActivePowerMinWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerMin::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeActivePowerMaxWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerMax::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeActivePowerMaxWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerMax::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeActivePowerMaxWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerMax::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeReactivePowerWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::ReactivePower::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeReactivePowerWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::ReactivePower::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeReactivePowerWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::ReactivePower::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeApparentPowerWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::ApparentPower::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeApparentPowerWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::ApparentPower::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeApparentPowerWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::ApparentPower::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePowerFactorWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::PowerFactor::TypeInfo;
    return MTRReadAttribute<MTRInt8sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePowerFactorWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::PowerFactor::TypeInfo;
    MTRSubscribeAttribute<MTRInt8sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePowerFactorWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::PowerFactor::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAverageRmsVoltageMeasurementPeriodWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsVoltageMeasurementPeriod::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeAverageRmsVoltageMeasurementPeriodWithValue:(NSNumber * _Nonnull)value
                                                       completion:(MTRStatusCompletion)completion
{
    [self writeAttributeAverageRmsVoltageMeasurementPeriodWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeAverageRmsVoltageMeasurementPeriodWithValue:(NSNumber * _Nonnull)value
                                                           params:(MTRWriteParams * _Nullable)params
                                                       completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsVoltageMeasurementPeriod::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeAverageRmsVoltageMeasurementPeriodWithParams:(MTRSubscribeParams * _Nonnull)params
                                               subscriptionEstablished:
                                                   (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                         reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsVoltageMeasurementPeriod::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAverageRmsVoltageMeasurementPeriodWithClusterStateCache:
            (MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                                    endpoint:(NSNumber *)endpoint
                                                                       queue:(dispatch_queue_t)queue
                                                                  completion:(void (^)(NSNumber * _Nullable value,
                                                                                 NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsVoltageMeasurementPeriod::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAverageRmsUnderVoltageCounterWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsUnderVoltageCounter::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeAverageRmsUnderVoltageCounterWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeAverageRmsUnderVoltageCounterWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeAverageRmsUnderVoltageCounterWithValue:(NSNumber * _Nonnull)value
                                                      params:(MTRWriteParams * _Nullable)params
                                                  completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsUnderVoltageCounter::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeAverageRmsUnderVoltageCounterWithParams:(MTRSubscribeParams * _Nonnull)params
                                          subscriptionEstablished:
                                              (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                    reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsUnderVoltageCounter::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAverageRmsUnderVoltageCounterWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                               endpoint:(NSNumber *)endpoint
                                                                  queue:(dispatch_queue_t)queue
                                                             completion:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsUnderVoltageCounter::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRmsExtremeOverVoltagePeriodWithCompletion:(void (^)(
                                                                   NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeOverVoltagePeriod::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeRmsExtremeOverVoltagePeriodWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeRmsExtremeOverVoltagePeriodWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeRmsExtremeOverVoltagePeriodWithValue:(NSNumber * _Nonnull)value
                                                    params:(MTRWriteParams * _Nullable)params
                                                completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeOverVoltagePeriod::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeRmsExtremeOverVoltagePeriodWithParams:(MTRSubscribeParams * _Nonnull)params
                                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeOverVoltagePeriod::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRmsExtremeOverVoltagePeriodWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                             endpoint:(NSNumber *)endpoint
                                                                queue:(dispatch_queue_t)queue
                                                           completion:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeOverVoltagePeriod::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRmsExtremeUnderVoltagePeriodWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeUnderVoltagePeriod::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeRmsExtremeUnderVoltagePeriodWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeRmsExtremeUnderVoltagePeriodWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeRmsExtremeUnderVoltagePeriodWithValue:(NSNumber * _Nonnull)value
                                                     params:(MTRWriteParams * _Nullable)params
                                                 completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeUnderVoltagePeriod::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeRmsExtremeUnderVoltagePeriodWithParams:(MTRSubscribeParams * _Nonnull)params
                                         subscriptionEstablished:
                                             (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                   reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeUnderVoltagePeriod::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRmsExtremeUnderVoltagePeriodWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                              endpoint:(NSNumber *)endpoint
                                                                 queue:(dispatch_queue_t)queue
                                                            completion:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeUnderVoltagePeriod::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRmsVoltageSagPeriodWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSagPeriod::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeRmsVoltageSagPeriodWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeRmsVoltageSagPeriodWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeRmsVoltageSagPeriodWithValue:(NSNumber * _Nonnull)value
                                            params:(MTRWriteParams * _Nullable)params
                                        completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSagPeriod::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeRmsVoltageSagPeriodWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSagPeriod::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRmsVoltageSagPeriodWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSagPeriod::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRmsVoltageSwellPeriodWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSwellPeriod::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeRmsVoltageSwellPeriodWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeRmsVoltageSwellPeriodWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeRmsVoltageSwellPeriodWithValue:(NSNumber * _Nonnull)value
                                              params:(MTRWriteParams * _Nullable)params
                                          completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSwellPeriod::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeRmsVoltageSwellPeriodWithParams:(MTRSubscribeParams * _Nonnull)params
                                  subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSwellPeriod::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRmsVoltageSwellPeriodWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                                     completion:
                                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSwellPeriod::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcVoltageMultiplierWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::AcVoltageMultiplier::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcVoltageMultiplierWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::AcVoltageMultiplier::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcVoltageMultiplierWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::AcVoltageMultiplier::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcVoltageDivisorWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::AcVoltageDivisor::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcVoltageDivisorWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::AcVoltageDivisor::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcVoltageDivisorWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::AcVoltageDivisor::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcCurrentMultiplierWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::AcCurrentMultiplier::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcCurrentMultiplierWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::AcCurrentMultiplier::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcCurrentMultiplierWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::AcCurrentMultiplier::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcCurrentDivisorWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::AcCurrentDivisor::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcCurrentDivisorWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::AcCurrentDivisor::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcCurrentDivisorWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::AcCurrentDivisor::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcPowerMultiplierWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::AcPowerMultiplier::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcPowerMultiplierWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::AcPowerMultiplier::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcPowerMultiplierWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::AcPowerMultiplier::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcPowerDivisorWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::AcPowerDivisor::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcPowerDivisorWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::AcPowerDivisor::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcPowerDivisorWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::AcPowerDivisor::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeOverloadAlarmsMaskWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::OverloadAlarmsMask::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeOverloadAlarmsMaskWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeOverloadAlarmsMaskWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeOverloadAlarmsMaskWithValue:(NSNumber * _Nonnull)value
                                           params:(MTRWriteParams * _Nullable)params
                                       completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ElectricalMeasurement::Attributes::OverloadAlarmsMask::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeOverloadAlarmsMaskWithParams:(MTRSubscribeParams * _Nonnull)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::OverloadAlarmsMask::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeOverloadAlarmsMaskWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                                  completion:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::OverloadAlarmsMask::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeVoltageOverloadWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::VoltageOverload::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeVoltageOverloadWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::VoltageOverload::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeVoltageOverloadWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::VoltageOverload::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCurrentOverloadWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::CurrentOverload::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeCurrentOverloadWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::CurrentOverload::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeCurrentOverloadWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::CurrentOverload::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcOverloadAlarmsMaskWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::AcOverloadAlarmsMask::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeAcOverloadAlarmsMaskWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeAcOverloadAlarmsMaskWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeAcOverloadAlarmsMaskWithValue:(NSNumber * _Nonnull)value
                                             params:(MTRWriteParams * _Nullable)params
                                         completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ElectricalMeasurement::Attributes::AcOverloadAlarmsMask::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeAcOverloadAlarmsMaskWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::AcOverloadAlarmsMask::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcOverloadAlarmsMaskWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::AcOverloadAlarmsMask::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcVoltageOverloadWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::AcVoltageOverload::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcVoltageOverloadWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::AcVoltageOverload::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcVoltageOverloadWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::AcVoltageOverload::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcCurrentOverloadWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::AcCurrentOverload::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcCurrentOverloadWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::AcCurrentOverload::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcCurrentOverloadWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::AcCurrentOverload::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcActivePowerOverloadWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::AcActivePowerOverload::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcActivePowerOverloadWithParams:(MTRSubscribeParams * _Nonnull)params
                                  subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::AcActivePowerOverload::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcActivePowerOverloadWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                                     completion:
                                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::AcActivePowerOverload::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcReactivePowerOverloadWithCompletion:(void (^)(
                                                               NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::AcReactivePowerOverload::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcReactivePowerOverloadWithParams:(MTRSubscribeParams * _Nonnull)params
                                    subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::AcReactivePowerOverload::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcReactivePowerOverloadWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                         endpoint:(NSNumber *)endpoint
                                                            queue:(dispatch_queue_t)queue
                                                       completion:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::AcReactivePowerOverload::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAverageRmsOverVoltageWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsOverVoltage::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAverageRmsOverVoltageWithParams:(MTRSubscribeParams * _Nonnull)params
                                  subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsOverVoltage::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAverageRmsOverVoltageWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                                     completion:
                                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsOverVoltage::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAverageRmsUnderVoltageWithCompletion:(void (^)(
                                                              NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsUnderVoltage::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAverageRmsUnderVoltageWithParams:(MTRSubscribeParams * _Nonnull)params
                                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsUnderVoltage::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAverageRmsUnderVoltageWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                                      completion:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsUnderVoltage::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRmsExtremeOverVoltageWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeOverVoltage::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRmsExtremeOverVoltageWithParams:(MTRSubscribeParams * _Nonnull)params
                                  subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeOverVoltage::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRmsExtremeOverVoltageWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                                     completion:
                                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeOverVoltage::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRmsExtremeUnderVoltageWithCompletion:(void (^)(
                                                              NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeUnderVoltage::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRmsExtremeUnderVoltageWithParams:(MTRSubscribeParams * _Nonnull)params
                                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeUnderVoltage::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRmsExtremeUnderVoltageWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                                      completion:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeUnderVoltage::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRmsVoltageSagWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSag::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRmsVoltageSagWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSag::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRmsVoltageSagWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSag::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRmsVoltageSwellWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSwell::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRmsVoltageSwellWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSwell::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRmsVoltageSwellWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSwell::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeLineCurrentPhaseBWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::LineCurrentPhaseB::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeLineCurrentPhaseBWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::LineCurrentPhaseB::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeLineCurrentPhaseBWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::LineCurrentPhaseB::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeActiveCurrentPhaseBWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::ActiveCurrentPhaseB::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeActiveCurrentPhaseBWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::ActiveCurrentPhaseB::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeActiveCurrentPhaseBWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::ActiveCurrentPhaseB::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeReactiveCurrentPhaseBWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::ReactiveCurrentPhaseB::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeReactiveCurrentPhaseBWithParams:(MTRSubscribeParams * _Nonnull)params
                                  subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::ReactiveCurrentPhaseB::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeReactiveCurrentPhaseBWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                                     completion:
                                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::ReactiveCurrentPhaseB::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRmsVoltagePhaseBWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltagePhaseB::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRmsVoltagePhaseBWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltagePhaseB::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRmsVoltagePhaseBWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltagePhaseB::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRmsVoltageMinPhaseBWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageMinPhaseB::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRmsVoltageMinPhaseBWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageMinPhaseB::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRmsVoltageMinPhaseBWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageMinPhaseB::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRmsVoltageMaxPhaseBWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageMaxPhaseB::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRmsVoltageMaxPhaseBWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageMaxPhaseB::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRmsVoltageMaxPhaseBWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageMaxPhaseB::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRmsCurrentPhaseBWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentPhaseB::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRmsCurrentPhaseBWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentPhaseB::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRmsCurrentPhaseBWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentPhaseB::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRmsCurrentMinPhaseBWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentMinPhaseB::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRmsCurrentMinPhaseBWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentMinPhaseB::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRmsCurrentMinPhaseBWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentMinPhaseB::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRmsCurrentMaxPhaseBWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentMaxPhaseB::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRmsCurrentMaxPhaseBWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentMaxPhaseB::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRmsCurrentMaxPhaseBWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentMaxPhaseB::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeActivePowerPhaseBWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerPhaseB::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeActivePowerPhaseBWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerPhaseB::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeActivePowerPhaseBWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerPhaseB::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeActivePowerMinPhaseBWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerMinPhaseB::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeActivePowerMinPhaseBWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerMinPhaseB::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeActivePowerMinPhaseBWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerMinPhaseB::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeActivePowerMaxPhaseBWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerMaxPhaseB::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeActivePowerMaxPhaseBWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerMaxPhaseB::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeActivePowerMaxPhaseBWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerMaxPhaseB::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeReactivePowerPhaseBWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::ReactivePowerPhaseB::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeReactivePowerPhaseBWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::ReactivePowerPhaseB::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeReactivePowerPhaseBWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::ReactivePowerPhaseB::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeApparentPowerPhaseBWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::ApparentPowerPhaseB::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeApparentPowerPhaseBWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::ApparentPowerPhaseB::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeApparentPowerPhaseBWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::ApparentPowerPhaseB::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePowerFactorPhaseBWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::PowerFactorPhaseB::TypeInfo;
    return MTRReadAttribute<MTRInt8sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePowerFactorPhaseBWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::PowerFactorPhaseB::TypeInfo;
    MTRSubscribeAttribute<MTRInt8sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePowerFactorPhaseBWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::PowerFactorPhaseB::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAverageRmsVoltageMeasurementPeriodPhaseBWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                                NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsVoltageMeasurementPeriodPhaseB::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAverageRmsVoltageMeasurementPeriodPhaseBWithParams:(MTRSubscribeParams * _Nonnull)params
                                                     subscriptionEstablished:
                                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                               reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                 NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsVoltageMeasurementPeriodPhaseB::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAverageRmsVoltageMeasurementPeriodPhaseBWithClusterStateCache:
            (MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                                          endpoint:(NSNumber *)endpoint
                                                                             queue:(dispatch_queue_t)queue
                                                                        completion:(void (^)(NSNumber * _Nullable value,
                                                                                       NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsVoltageMeasurementPeriodPhaseB::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAverageRmsOverVoltageCounterPhaseBWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsOverVoltageCounterPhaseB::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAverageRmsOverVoltageCounterPhaseBWithParams:(MTRSubscribeParams * _Nonnull)params
                                               subscriptionEstablished:
                                                   (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                         reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsOverVoltageCounterPhaseB::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAverageRmsOverVoltageCounterPhaseBWithClusterStateCache:
            (MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                                    endpoint:(NSNumber *)endpoint
                                                                       queue:(dispatch_queue_t)queue
                                                                  completion:(void (^)(NSNumber * _Nullable value,
                                                                                 NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsOverVoltageCounterPhaseB::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAverageRmsUnderVoltageCounterPhaseBWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsUnderVoltageCounterPhaseB::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAverageRmsUnderVoltageCounterPhaseBWithParams:(MTRSubscribeParams * _Nonnull)params
                                                subscriptionEstablished:
                                                    (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                          reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsUnderVoltageCounterPhaseB::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAverageRmsUnderVoltageCounterPhaseBWithClusterStateCache:
            (MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                                     endpoint:(NSNumber *)endpoint
                                                                        queue:(dispatch_queue_t)queue
                                                                   completion:(void (^)(NSNumber * _Nullable value,
                                                                                  NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsUnderVoltageCounterPhaseB::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRmsExtremeOverVoltagePeriodPhaseBWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeOverVoltagePeriodPhaseB::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRmsExtremeOverVoltagePeriodPhaseBWithParams:(MTRSubscribeParams * _Nonnull)params
                                              subscriptionEstablished:
                                                  (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                        reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeOverVoltagePeriodPhaseB::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRmsExtremeOverVoltagePeriodPhaseBWithClusterStateCache:
            (MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                                   endpoint:(NSNumber *)endpoint
                                                                      queue:(dispatch_queue_t)queue
                                                                 completion:(void (^)(NSNumber * _Nullable value,
                                                                                NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeOverVoltagePeriodPhaseB::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRmsExtremeUnderVoltagePeriodPhaseBWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeUnderVoltagePeriodPhaseB::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRmsExtremeUnderVoltagePeriodPhaseBWithParams:(MTRSubscribeParams * _Nonnull)params
                                               subscriptionEstablished:
                                                   (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                         reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeUnderVoltagePeriodPhaseB::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRmsExtremeUnderVoltagePeriodPhaseBWithClusterStateCache:
            (MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                                    endpoint:(NSNumber *)endpoint
                                                                       queue:(dispatch_queue_t)queue
                                                                  completion:(void (^)(NSNumber * _Nullable value,
                                                                                 NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeUnderVoltagePeriodPhaseB::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRmsVoltageSagPeriodPhaseBWithCompletion:(void (^)(
                                                                 NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSagPeriodPhaseB::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRmsVoltageSagPeriodPhaseBWithParams:(MTRSubscribeParams * _Nonnull)params
                                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSagPeriodPhaseB::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRmsVoltageSagPeriodPhaseBWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                           endpoint:(NSNumber *)endpoint
                                                              queue:(dispatch_queue_t)queue
                                                         completion:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSagPeriodPhaseB::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRmsVoltageSwellPeriodPhaseBWithCompletion:(void (^)(
                                                                   NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSwellPeriodPhaseB::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRmsVoltageSwellPeriodPhaseBWithParams:(MTRSubscribeParams * _Nonnull)params
                                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSwellPeriodPhaseB::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRmsVoltageSwellPeriodPhaseBWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                             endpoint:(NSNumber *)endpoint
                                                                queue:(dispatch_queue_t)queue
                                                           completion:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSwellPeriodPhaseB::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeLineCurrentPhaseCWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::LineCurrentPhaseC::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeLineCurrentPhaseCWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::LineCurrentPhaseC::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeLineCurrentPhaseCWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::LineCurrentPhaseC::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeActiveCurrentPhaseCWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::ActiveCurrentPhaseC::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeActiveCurrentPhaseCWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::ActiveCurrentPhaseC::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeActiveCurrentPhaseCWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::ActiveCurrentPhaseC::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeReactiveCurrentPhaseCWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::ReactiveCurrentPhaseC::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeReactiveCurrentPhaseCWithParams:(MTRSubscribeParams * _Nonnull)params
                                  subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::ReactiveCurrentPhaseC::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeReactiveCurrentPhaseCWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                                     completion:
                                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::ReactiveCurrentPhaseC::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRmsVoltagePhaseCWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltagePhaseC::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRmsVoltagePhaseCWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltagePhaseC::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRmsVoltagePhaseCWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltagePhaseC::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRmsVoltageMinPhaseCWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageMinPhaseC::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRmsVoltageMinPhaseCWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageMinPhaseC::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRmsVoltageMinPhaseCWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageMinPhaseC::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRmsVoltageMaxPhaseCWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageMaxPhaseC::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRmsVoltageMaxPhaseCWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageMaxPhaseC::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRmsVoltageMaxPhaseCWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageMaxPhaseC::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRmsCurrentPhaseCWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentPhaseC::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRmsCurrentPhaseCWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentPhaseC::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRmsCurrentPhaseCWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentPhaseC::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRmsCurrentMinPhaseCWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentMinPhaseC::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRmsCurrentMinPhaseCWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentMinPhaseC::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRmsCurrentMinPhaseCWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentMinPhaseC::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRmsCurrentMaxPhaseCWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentMaxPhaseC::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRmsCurrentMaxPhaseCWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentMaxPhaseC::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRmsCurrentMaxPhaseCWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentMaxPhaseC::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeActivePowerPhaseCWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerPhaseC::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeActivePowerPhaseCWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerPhaseC::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeActivePowerPhaseCWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerPhaseC::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeActivePowerMinPhaseCWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerMinPhaseC::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeActivePowerMinPhaseCWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerMinPhaseC::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeActivePowerMinPhaseCWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerMinPhaseC::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeActivePowerMaxPhaseCWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerMaxPhaseC::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeActivePowerMaxPhaseCWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerMaxPhaseC::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeActivePowerMaxPhaseCWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerMaxPhaseC::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeReactivePowerPhaseCWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::ReactivePowerPhaseC::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeReactivePowerPhaseCWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::ReactivePowerPhaseC::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeReactivePowerPhaseCWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::ReactivePowerPhaseC::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeApparentPowerPhaseCWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::ApparentPowerPhaseC::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeApparentPowerPhaseCWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::ApparentPowerPhaseC::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeApparentPowerPhaseCWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::ApparentPowerPhaseC::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePowerFactorPhaseCWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::PowerFactorPhaseC::TypeInfo;
    return MTRReadAttribute<MTRInt8sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributePowerFactorPhaseCWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::PowerFactorPhaseC::TypeInfo;
    MTRSubscribeAttribute<MTRInt8sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributePowerFactorPhaseCWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::PowerFactorPhaseC::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAverageRmsVoltageMeasurementPeriodPhaseCWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                                NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsVoltageMeasurementPeriodPhaseC::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAverageRmsVoltageMeasurementPeriodPhaseCWithParams:(MTRSubscribeParams * _Nonnull)params
                                                     subscriptionEstablished:
                                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                               reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                 NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsVoltageMeasurementPeriodPhaseC::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAverageRmsVoltageMeasurementPeriodPhaseCWithClusterStateCache:
            (MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                                          endpoint:(NSNumber *)endpoint
                                                                             queue:(dispatch_queue_t)queue
                                                                        completion:(void (^)(NSNumber * _Nullable value,
                                                                                       NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsVoltageMeasurementPeriodPhaseC::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAverageRmsOverVoltageCounterPhaseCWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsOverVoltageCounterPhaseC::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAverageRmsOverVoltageCounterPhaseCWithParams:(MTRSubscribeParams * _Nonnull)params
                                               subscriptionEstablished:
                                                   (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                         reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsOverVoltageCounterPhaseC::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAverageRmsOverVoltageCounterPhaseCWithClusterStateCache:
            (MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                                    endpoint:(NSNumber *)endpoint
                                                                       queue:(dispatch_queue_t)queue
                                                                  completion:(void (^)(NSNumber * _Nullable value,
                                                                                 NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsOverVoltageCounterPhaseC::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAverageRmsUnderVoltageCounterPhaseCWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsUnderVoltageCounterPhaseC::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAverageRmsUnderVoltageCounterPhaseCWithParams:(MTRSubscribeParams * _Nonnull)params
                                                subscriptionEstablished:
                                                    (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                          reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsUnderVoltageCounterPhaseC::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAverageRmsUnderVoltageCounterPhaseCWithClusterStateCache:
            (MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                                     endpoint:(NSNumber *)endpoint
                                                                        queue:(dispatch_queue_t)queue
                                                                   completion:(void (^)(NSNumber * _Nullable value,
                                                                                  NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsUnderVoltageCounterPhaseC::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRmsExtremeOverVoltagePeriodPhaseCWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeOverVoltagePeriodPhaseC::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRmsExtremeOverVoltagePeriodPhaseCWithParams:(MTRSubscribeParams * _Nonnull)params
                                              subscriptionEstablished:
                                                  (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                        reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeOverVoltagePeriodPhaseC::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRmsExtremeOverVoltagePeriodPhaseCWithClusterStateCache:
            (MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                                   endpoint:(NSNumber *)endpoint
                                                                      queue:(dispatch_queue_t)queue
                                                                 completion:(void (^)(NSNumber * _Nullable value,
                                                                                NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeOverVoltagePeriodPhaseC::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRmsExtremeUnderVoltagePeriodPhaseCWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeUnderVoltagePeriodPhaseC::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRmsExtremeUnderVoltagePeriodPhaseCWithParams:(MTRSubscribeParams * _Nonnull)params
                                               subscriptionEstablished:
                                                   (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                         reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeUnderVoltagePeriodPhaseC::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRmsExtremeUnderVoltagePeriodPhaseCWithClusterStateCache:
            (MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                                    endpoint:(NSNumber *)endpoint
                                                                       queue:(dispatch_queue_t)queue
                                                                  completion:(void (^)(NSNumber * _Nullable value,
                                                                                 NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeUnderVoltagePeriodPhaseC::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRmsVoltageSagPeriodPhaseCWithCompletion:(void (^)(
                                                                 NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSagPeriodPhaseC::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRmsVoltageSagPeriodPhaseCWithParams:(MTRSubscribeParams * _Nonnull)params
                                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSagPeriodPhaseC::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRmsVoltageSagPeriodPhaseCWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                           endpoint:(NSNumber *)endpoint
                                                              queue:(dispatch_queue_t)queue
                                                         completion:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSagPeriodPhaseC::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRmsVoltageSwellPeriodPhaseCWithCompletion:(void (^)(
                                                                   NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSwellPeriodPhaseC::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeRmsVoltageSwellPeriodPhaseCWithParams:(MTRSubscribeParams * _Nonnull)params
                                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSwellPeriodPhaseC::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRmsVoltageSwellPeriodPhaseCWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                             endpoint:(NSNumber *)endpoint
                                                                queue:(dispatch_queue_t)queue
                                                           completion:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSwellPeriodPhaseC::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRElectricalMeasurementGeneratedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRElectricalMeasurementGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRElectricalMeasurementGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ElectricalMeasurementGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRElectricalMeasurementAcceptedCommandListListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRElectricalMeasurementAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRElectricalMeasurementAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ElectricalMeasurementAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRElectricalMeasurementEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRElectricalMeasurementEventListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRElectricalMeasurementEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ElectricalMeasurementEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRElectricalMeasurementAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRElectricalMeasurementAttributeListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRElectricalMeasurementAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(ElectricalMeasurementAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = ElectricalMeasurement::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = ElectricalMeasurement::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterElectricalMeasurement (Deprecated)

- (void)getProfileInfoCommandWithParams:(MTRElectricalMeasurementClusterGetProfileInfoCommandParams * _Nullable)params
                      completionHandler:(MTRStatusCompletion)completionHandler
{
    [self getProfileInfoCommandWithParams:params completion:completionHandler];
}
- (void)getProfileInfoCommandWithCompletionHandler:(MTRStatusCompletion)completionHandler
{
    [self getProfileInfoCommandWithParams:nil completionHandler:completionHandler];
}
- (void)getMeasurementProfileCommandWithParams:(MTRElectricalMeasurementClusterGetMeasurementProfileCommandParams *)params
                             completionHandler:(MTRStatusCompletion)completionHandler
{
    [self getMeasurementProfileCommandWithParams:params completion:completionHandler];
}

- (void)readAttributeMeasurementTypeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeMeasurementTypeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeMeasurementTypeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMeasurementTypeWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeMeasurementTypeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeMeasurementTypeWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (void)readAttributeDcVoltageWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDcVoltageWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeDcVoltageWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeDcVoltageWithParams:subscribeParams
                        subscriptionEstablished:subscriptionEstablishedHandler
                                  reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                      // Cast is safe because subclass does not add any selectors.
                                      reportHandler(static_cast<NSNumber *>(value), error);
                                  }];
}
+ (void)readAttributeDcVoltageWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDcVoltageWithClusterStateCache:attributeCacheContainer.realContainer
                                             endpoint:endpoint
                                                queue:queue
                                           completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               completionHandler(static_cast<NSNumber *>(value), error);
                                           }];
}

- (void)readAttributeDcVoltageMinWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDcVoltageMinWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeDcVoltageMinWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeDcVoltageMinWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributeDcVoltageMinWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDcVoltageMinWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributeDcVoltageMaxWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDcVoltageMaxWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeDcVoltageMaxWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeDcVoltageMaxWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributeDcVoltageMaxWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDcVoltageMaxWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributeDcCurrentWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDcCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeDcCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeDcCurrentWithParams:subscribeParams
                        subscriptionEstablished:subscriptionEstablishedHandler
                                  reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                      // Cast is safe because subclass does not add any selectors.
                                      reportHandler(static_cast<NSNumber *>(value), error);
                                  }];
}
+ (void)readAttributeDcCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDcCurrentWithClusterStateCache:attributeCacheContainer.realContainer
                                             endpoint:endpoint
                                                queue:queue
                                           completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               completionHandler(static_cast<NSNumber *>(value), error);
                                           }];
}

- (void)readAttributeDcCurrentMinWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDcCurrentMinWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeDcCurrentMinWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeDcCurrentMinWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributeDcCurrentMinWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDcCurrentMinWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributeDcCurrentMaxWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDcCurrentMaxWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeDcCurrentMaxWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeDcCurrentMaxWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributeDcCurrentMaxWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDcCurrentMaxWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributeDcPowerWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDcPowerWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeDcPowerWithMinInterval:(NSNumber * _Nonnull)minInterval
                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                          params:(MTRSubscribeParams * _Nullable)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeDcPowerWithParams:subscribeParams
                      subscriptionEstablished:subscriptionEstablishedHandler
                                reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                    // Cast is safe because subclass does not add any selectors.
                                    reportHandler(static_cast<NSNumber *>(value), error);
                                }];
}
+ (void)readAttributeDcPowerWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                      endpoint:(NSNumber *)endpoint
                                         queue:(dispatch_queue_t)queue
                             completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDcPowerWithClusterStateCache:attributeCacheContainer.realContainer
                                           endpoint:endpoint
                                              queue:queue
                                         completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             completionHandler(static_cast<NSNumber *>(value), error);
                                         }];
}

- (void)readAttributeDcPowerMinWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDcPowerMinWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeDcPowerMinWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeDcPowerMinWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeDcPowerMinWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDcPowerMinWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeDcPowerMaxWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDcPowerMaxWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeDcPowerMaxWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeDcPowerMaxWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeDcPowerMaxWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDcPowerMaxWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeDcVoltageMultiplierWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeDcVoltageMultiplierWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeDcVoltageMultiplierWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeDcVoltageMultiplierWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSNumber *>(value), error);
                                            }];
}
+ (void)readAttributeDcVoltageMultiplierWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDcVoltageMultiplierWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}

- (void)readAttributeDcVoltageDivisorWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeDcVoltageDivisorWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)
    subscribeAttributeDcVoltageDivisorWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeDcVoltageDivisorWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributeDcVoltageDivisorWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDcVoltageDivisorWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeDcCurrentMultiplierWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeDcCurrentMultiplierWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeDcCurrentMultiplierWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeDcCurrentMultiplierWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSNumber *>(value), error);
                                            }];
}
+ (void)readAttributeDcCurrentMultiplierWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDcCurrentMultiplierWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}

- (void)readAttributeDcCurrentDivisorWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeDcCurrentDivisorWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)
    subscribeAttributeDcCurrentDivisorWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeDcCurrentDivisorWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributeDcCurrentDivisorWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDcCurrentDivisorWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeDcPowerMultiplierWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeDcPowerMultiplierWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeDcPowerMultiplierWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeDcPowerMultiplierWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSNumber *>(value), error);
                                          }];
}
+ (void)readAttributeDcPowerMultiplierWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDcPowerMultiplierWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}

- (void)readAttributeDcPowerDivisorWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeDcPowerDivisorWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeDcPowerDivisorWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeDcPowerDivisorWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSNumber *>(value), error);
                                       }];
}
+ (void)readAttributeDcPowerDivisorWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeDcPowerDivisorWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSNumber *>(value), error);
                                                }];
}

- (void)readAttributeAcFrequencyWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcFrequencyWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeAcFrequencyWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcFrequencyWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSNumber *>(value), error);
                                    }];
}
+ (void)readAttributeAcFrequencyWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcFrequencyWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                             }];
}

- (void)readAttributeAcFrequencyMinWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeAcFrequencyMinWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeAcFrequencyMinWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcFrequencyMinWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSNumber *>(value), error);
                                       }];
}
+ (void)readAttributeAcFrequencyMinWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcFrequencyMinWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSNumber *>(value), error);
                                                }];
}

- (void)readAttributeAcFrequencyMaxWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeAcFrequencyMaxWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeAcFrequencyMaxWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcFrequencyMaxWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSNumber *>(value), error);
                                       }];
}
+ (void)readAttributeAcFrequencyMaxWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcFrequencyMaxWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSNumber *>(value), error);
                                                }];
}

- (void)readAttributeNeutralCurrentWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeNeutralCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeNeutralCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNeutralCurrentWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSNumber *>(value), error);
                                       }];
}
+ (void)readAttributeNeutralCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNeutralCurrentWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSNumber *>(value), error);
                                                }];
}

- (void)readAttributeTotalActivePowerWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeTotalActivePowerWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)
    subscribeAttributeTotalActivePowerWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeTotalActivePowerWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributeTotalActivePowerWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeTotalActivePowerWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeTotalReactivePowerWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    [self readAttributeTotalReactivePowerWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeTotalReactivePowerWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:
                                        (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeTotalReactivePowerWithParams:subscribeParams
                                 subscriptionEstablished:subscriptionEstablishedHandler
                                           reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               reportHandler(static_cast<NSNumber *>(value), error);
                                           }];
}
+ (void)readAttributeTotalReactivePowerWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeTotalReactivePowerWithClusterStateCache:attributeCacheContainer.realContainer
                                                      endpoint:endpoint
                                                         queue:queue
                                                    completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                        // Cast is safe because subclass does not add any selectors.
                                                        completionHandler(static_cast<NSNumber *>(value), error);
                                                    }];
}

- (void)readAttributeTotalApparentPowerWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    [self readAttributeTotalApparentPowerWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeTotalApparentPowerWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:
                                        (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeTotalApparentPowerWithParams:subscribeParams
                                 subscriptionEstablished:subscriptionEstablishedHandler
                                           reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               reportHandler(static_cast<NSNumber *>(value), error);
                                           }];
}
+ (void)readAttributeTotalApparentPowerWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeTotalApparentPowerWithClusterStateCache:attributeCacheContainer.realContainer
                                                      endpoint:endpoint
                                                         queue:queue
                                                    completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                        // Cast is safe because subclass does not add any selectors.
                                                        completionHandler(static_cast<NSNumber *>(value), error);
                                                    }];
}

- (void)readAttributeMeasured1stHarmonicCurrentWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    [self readAttributeMeasured1stHarmonicCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeMeasured1stHarmonicCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                                             params:(MTRSubscribeParams * _Nullable)params
                                            subscriptionEstablished:
                                                (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                      reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMeasured1stHarmonicCurrentWithParams:subscribeParams
                                         subscriptionEstablished:subscriptionEstablishedHandler
                                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       reportHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}
+ (void)readAttributeMeasured1stHarmonicCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                         endpoint:(NSNumber *)endpoint
                                                            queue:(dispatch_queue_t)queue
                                                completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    [self readAttributeMeasured1stHarmonicCurrentWithClusterStateCache:attributeCacheContainer.realContainer
                                                              endpoint:endpoint
                                                                 queue:queue
                                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                // Cast is safe because subclass does not add any selectors.
                                                                completionHandler(static_cast<NSNumber *>(value), error);
                                                            }];
}

- (void)readAttributeMeasured3rdHarmonicCurrentWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    [self readAttributeMeasured3rdHarmonicCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeMeasured3rdHarmonicCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                                             params:(MTRSubscribeParams * _Nullable)params
                                            subscriptionEstablished:
                                                (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                      reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMeasured3rdHarmonicCurrentWithParams:subscribeParams
                                         subscriptionEstablished:subscriptionEstablishedHandler
                                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       reportHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}
+ (void)readAttributeMeasured3rdHarmonicCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                         endpoint:(NSNumber *)endpoint
                                                            queue:(dispatch_queue_t)queue
                                                completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    [self readAttributeMeasured3rdHarmonicCurrentWithClusterStateCache:attributeCacheContainer.realContainer
                                                              endpoint:endpoint
                                                                 queue:queue
                                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                // Cast is safe because subclass does not add any selectors.
                                                                completionHandler(static_cast<NSNumber *>(value), error);
                                                            }];
}

- (void)readAttributeMeasured5thHarmonicCurrentWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    [self readAttributeMeasured5thHarmonicCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeMeasured5thHarmonicCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                                             params:(MTRSubscribeParams * _Nullable)params
                                            subscriptionEstablished:
                                                (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                      reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMeasured5thHarmonicCurrentWithParams:subscribeParams
                                         subscriptionEstablished:subscriptionEstablishedHandler
                                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       reportHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}
+ (void)readAttributeMeasured5thHarmonicCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                         endpoint:(NSNumber *)endpoint
                                                            queue:(dispatch_queue_t)queue
                                                completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    [self readAttributeMeasured5thHarmonicCurrentWithClusterStateCache:attributeCacheContainer.realContainer
                                                              endpoint:endpoint
                                                                 queue:queue
                                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                // Cast is safe because subclass does not add any selectors.
                                                                completionHandler(static_cast<NSNumber *>(value), error);
                                                            }];
}

- (void)readAttributeMeasured7thHarmonicCurrentWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    [self readAttributeMeasured7thHarmonicCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeMeasured7thHarmonicCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                                             params:(MTRSubscribeParams * _Nullable)params
                                            subscriptionEstablished:
                                                (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                      reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMeasured7thHarmonicCurrentWithParams:subscribeParams
                                         subscriptionEstablished:subscriptionEstablishedHandler
                                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       reportHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}
+ (void)readAttributeMeasured7thHarmonicCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                         endpoint:(NSNumber *)endpoint
                                                            queue:(dispatch_queue_t)queue
                                                completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    [self readAttributeMeasured7thHarmonicCurrentWithClusterStateCache:attributeCacheContainer.realContainer
                                                              endpoint:endpoint
                                                                 queue:queue
                                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                // Cast is safe because subclass does not add any selectors.
                                                                completionHandler(static_cast<NSNumber *>(value), error);
                                                            }];
}

- (void)readAttributeMeasured9thHarmonicCurrentWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    [self readAttributeMeasured9thHarmonicCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeMeasured9thHarmonicCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                                             params:(MTRSubscribeParams * _Nullable)params
                                            subscriptionEstablished:
                                                (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                      reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMeasured9thHarmonicCurrentWithParams:subscribeParams
                                         subscriptionEstablished:subscriptionEstablishedHandler
                                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       reportHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}
+ (void)readAttributeMeasured9thHarmonicCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                         endpoint:(NSNumber *)endpoint
                                                            queue:(dispatch_queue_t)queue
                                                completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    [self readAttributeMeasured9thHarmonicCurrentWithClusterStateCache:attributeCacheContainer.realContainer
                                                              endpoint:endpoint
                                                                 queue:queue
                                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                // Cast is safe because subclass does not add any selectors.
                                                                completionHandler(static_cast<NSNumber *>(value), error);
                                                            }];
}

- (void)readAttributeMeasured11thHarmonicCurrentWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))completionHandler
{
    [self readAttributeMeasured11thHarmonicCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeMeasured11thHarmonicCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                                              params:(MTRSubscribeParams * _Nullable)params
                                             subscriptionEstablished:
                                                 (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                       reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMeasured11thHarmonicCurrentWithParams:subscribeParams
                                          subscriptionEstablished:subscriptionEstablishedHandler
                                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                        // Cast is safe because subclass does not add any selectors.
                                                        reportHandler(static_cast<NSNumber *>(value), error);
                                                    }];
}
+ (void)readAttributeMeasured11thHarmonicCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                          endpoint:(NSNumber *)endpoint
                                                             queue:(dispatch_queue_t)queue
                                                 completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completionHandler
{
    [self readAttributeMeasured11thHarmonicCurrentWithClusterStateCache:attributeCacheContainer.realContainer
                                                               endpoint:endpoint
                                                                  queue:queue
                                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                 // Cast is safe because subclass does not add any selectors.
                                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                                             }];
}

- (void)readAttributeMeasuredPhase1stHarmonicCurrentWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeMeasuredPhase1stHarmonicCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeMeasuredPhase1stHarmonicCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                  params:(MTRSubscribeParams * _Nullable)params
                                                 subscriptionEstablished:
                                                     (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                           reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                             NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMeasuredPhase1stHarmonicCurrentWithParams:subscribeParams
                                              subscriptionEstablished:subscriptionEstablishedHandler
                                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                            // Cast is safe because subclass does not add any selectors.
                                                            reportHandler(static_cast<NSNumber *>(value), error);
                                                        }];
}
+ (void)readAttributeMeasuredPhase1stHarmonicCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                              endpoint:(NSNumber *)endpoint
                                                                 queue:(dispatch_queue_t)queue
                                                     completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completionHandler
{
    [self
        readAttributeMeasuredPhase1stHarmonicCurrentWithClusterStateCache:attributeCacheContainer.realContainer
                                                                 endpoint:endpoint
                                                                    queue:queue
                                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                   // Cast is safe because subclass does not add any selectors.
                                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                                               }];
}

- (void)readAttributeMeasuredPhase3rdHarmonicCurrentWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeMeasuredPhase3rdHarmonicCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeMeasuredPhase3rdHarmonicCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                  params:(MTRSubscribeParams * _Nullable)params
                                                 subscriptionEstablished:
                                                     (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                           reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                             NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMeasuredPhase3rdHarmonicCurrentWithParams:subscribeParams
                                              subscriptionEstablished:subscriptionEstablishedHandler
                                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                            // Cast is safe because subclass does not add any selectors.
                                                            reportHandler(static_cast<NSNumber *>(value), error);
                                                        }];
}
+ (void)readAttributeMeasuredPhase3rdHarmonicCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                              endpoint:(NSNumber *)endpoint
                                                                 queue:(dispatch_queue_t)queue
                                                     completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completionHandler
{
    [self
        readAttributeMeasuredPhase3rdHarmonicCurrentWithClusterStateCache:attributeCacheContainer.realContainer
                                                                 endpoint:endpoint
                                                                    queue:queue
                                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                   // Cast is safe because subclass does not add any selectors.
                                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                                               }];
}

- (void)readAttributeMeasuredPhase5thHarmonicCurrentWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeMeasuredPhase5thHarmonicCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeMeasuredPhase5thHarmonicCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                  params:(MTRSubscribeParams * _Nullable)params
                                                 subscriptionEstablished:
                                                     (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                           reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                             NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMeasuredPhase5thHarmonicCurrentWithParams:subscribeParams
                                              subscriptionEstablished:subscriptionEstablishedHandler
                                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                            // Cast is safe because subclass does not add any selectors.
                                                            reportHandler(static_cast<NSNumber *>(value), error);
                                                        }];
}
+ (void)readAttributeMeasuredPhase5thHarmonicCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                              endpoint:(NSNumber *)endpoint
                                                                 queue:(dispatch_queue_t)queue
                                                     completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completionHandler
{
    [self
        readAttributeMeasuredPhase5thHarmonicCurrentWithClusterStateCache:attributeCacheContainer.realContainer
                                                                 endpoint:endpoint
                                                                    queue:queue
                                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                   // Cast is safe because subclass does not add any selectors.
                                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                                               }];
}

- (void)readAttributeMeasuredPhase7thHarmonicCurrentWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeMeasuredPhase7thHarmonicCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeMeasuredPhase7thHarmonicCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                  params:(MTRSubscribeParams * _Nullable)params
                                                 subscriptionEstablished:
                                                     (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                           reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                             NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMeasuredPhase7thHarmonicCurrentWithParams:subscribeParams
                                              subscriptionEstablished:subscriptionEstablishedHandler
                                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                            // Cast is safe because subclass does not add any selectors.
                                                            reportHandler(static_cast<NSNumber *>(value), error);
                                                        }];
}
+ (void)readAttributeMeasuredPhase7thHarmonicCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                              endpoint:(NSNumber *)endpoint
                                                                 queue:(dispatch_queue_t)queue
                                                     completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completionHandler
{
    [self
        readAttributeMeasuredPhase7thHarmonicCurrentWithClusterStateCache:attributeCacheContainer.realContainer
                                                                 endpoint:endpoint
                                                                    queue:queue
                                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                   // Cast is safe because subclass does not add any selectors.
                                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                                               }];
}

- (void)readAttributeMeasuredPhase9thHarmonicCurrentWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeMeasuredPhase9thHarmonicCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeMeasuredPhase9thHarmonicCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                  params:(MTRSubscribeParams * _Nullable)params
                                                 subscriptionEstablished:
                                                     (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                           reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                             NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMeasuredPhase9thHarmonicCurrentWithParams:subscribeParams
                                              subscriptionEstablished:subscriptionEstablishedHandler
                                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                            // Cast is safe because subclass does not add any selectors.
                                                            reportHandler(static_cast<NSNumber *>(value), error);
                                                        }];
}
+ (void)readAttributeMeasuredPhase9thHarmonicCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                              endpoint:(NSNumber *)endpoint
                                                                 queue:(dispatch_queue_t)queue
                                                     completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completionHandler
{
    [self
        readAttributeMeasuredPhase9thHarmonicCurrentWithClusterStateCache:attributeCacheContainer.realContainer
                                                                 endpoint:endpoint
                                                                    queue:queue
                                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                   // Cast is safe because subclass does not add any selectors.
                                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                                               }];
}

- (void)readAttributeMeasuredPhase11thHarmonicCurrentWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeMeasuredPhase11thHarmonicCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeMeasuredPhase11thHarmonicCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                   params:(MTRSubscribeParams * _Nullable)params
                                                  subscriptionEstablished:
                                                      (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                            reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeMeasuredPhase11thHarmonicCurrentWithParams:subscribeParams
                                               subscriptionEstablished:subscriptionEstablishedHandler
                                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                             // Cast is safe because subclass does not add any selectors.
                                                             reportHandler(static_cast<NSNumber *>(value), error);
                                                         }];
}
+ (void)readAttributeMeasuredPhase11thHarmonicCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                               endpoint:(NSNumber *)endpoint
                                                                  queue:(dispatch_queue_t)queue
                                                      completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))completionHandler
{
    [self readAttributeMeasuredPhase11thHarmonicCurrentWithClusterStateCache:attributeCacheContainer.realContainer
                                                                    endpoint:endpoint
                                                                       queue:queue
                                                                  completion:^(
                                                                      NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                      // Cast is safe because subclass does not add any selectors.
                                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                                  }];
}

- (void)readAttributeAcFrequencyMultiplierWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    [self readAttributeAcFrequencyMultiplierWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeAcFrequencyMultiplierWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcFrequencyMultiplierWithParams:subscribeParams
                                    subscriptionEstablished:subscriptionEstablishedHandler
                                              reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  reportHandler(static_cast<NSNumber *>(value), error);
                                              }];
}
+ (void)readAttributeAcFrequencyMultiplierWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcFrequencyMultiplierWithClusterStateCache:attributeCacheContainer.realContainer
                                                         endpoint:endpoint
                                                            queue:queue
                                                       completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                           // Cast is safe because subclass does not add any selectors.
                                                           completionHandler(static_cast<NSNumber *>(value), error);
                                                       }];
}

- (void)readAttributeAcFrequencyDivisorWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    [self readAttributeAcFrequencyDivisorWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeAcFrequencyDivisorWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:
                                        (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcFrequencyDivisorWithParams:subscribeParams
                                 subscriptionEstablished:subscriptionEstablishedHandler
                                           reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               reportHandler(static_cast<NSNumber *>(value), error);
                                           }];
}
+ (void)readAttributeAcFrequencyDivisorWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcFrequencyDivisorWithClusterStateCache:attributeCacheContainer.realContainer
                                                      endpoint:endpoint
                                                         queue:queue
                                                    completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                        // Cast is safe because subclass does not add any selectors.
                                                        completionHandler(static_cast<NSNumber *>(value), error);
                                                    }];
}

- (void)readAttributePowerMultiplierWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributePowerMultiplierWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributePowerMultiplierWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePowerMultiplierWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributePowerMultiplierWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePowerMultiplierWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (void)readAttributePowerDivisorWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePowerDivisorWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributePowerDivisorWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePowerDivisorWithParams:subscribeParams
                           subscriptionEstablished:subscriptionEstablishedHandler
                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         reportHandler(static_cast<NSNumber *>(value), error);
                                     }];
}
+ (void)readAttributePowerDivisorWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePowerDivisorWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                              }];
}

- (void)readAttributeHarmonicCurrentMultiplierWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    [self readAttributeHarmonicCurrentMultiplierWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeHarmonicCurrentMultiplierWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                                            params:(MTRSubscribeParams * _Nullable)params
                                           subscriptionEstablished:
                                               (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                     reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeHarmonicCurrentMultiplierWithParams:subscribeParams
                                        subscriptionEstablished:subscriptionEstablishedHandler
                                                  reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      reportHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}
+ (void)readAttributeHarmonicCurrentMultiplierWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                               completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    [self readAttributeHarmonicCurrentMultiplierWithClusterStateCache:attributeCacheContainer.realContainer
                                                             endpoint:endpoint
                                                                queue:queue
                                                           completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                               // Cast is safe because subclass does not add any selectors.
                                                               completionHandler(static_cast<NSNumber *>(value), error);
                                                           }];
}

- (void)readAttributePhaseHarmonicCurrentMultiplierWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributePhaseHarmonicCurrentMultiplierWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributePhaseHarmonicCurrentMultiplierWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                 params:(MTRSubscribeParams * _Nullable)params
                                                subscriptionEstablished:
                                                    (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                          reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePhaseHarmonicCurrentMultiplierWithParams:subscribeParams
                                             subscriptionEstablished:subscriptionEstablishedHandler
                                                       reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                           // Cast is safe because subclass does not add any selectors.
                                                           reportHandler(static_cast<NSNumber *>(value), error);
                                                       }];
}
+ (void)readAttributePhaseHarmonicCurrentMultiplierWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                             endpoint:(NSNumber *)endpoint
                                                                queue:(dispatch_queue_t)queue
                                                    completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))completionHandler
{
    [self
        readAttributePhaseHarmonicCurrentMultiplierWithClusterStateCache:attributeCacheContainer.realContainer
                                                                endpoint:endpoint
                                                                   queue:queue
                                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                  // Cast is safe because subclass does not add any selectors.
                                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                                              }];
}

- (void)readAttributeInstantaneousVoltageWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeInstantaneousVoltageWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeInstantaneousVoltageWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeInstantaneousVoltageWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSNumber *>(value), error);
                                             }];
}
+ (void)readAttributeInstantaneousVoltageWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInstantaneousVoltageWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSNumber *>(value), error);
                                                      }];
}

- (void)readAttributeInstantaneousLineCurrentWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completionHandler
{
    [self readAttributeInstantaneousLineCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeInstantaneousLineCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                                           params:(MTRSubscribeParams * _Nullable)params
                                          subscriptionEstablished:
                                              (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                    reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeInstantaneousLineCurrentWithParams:subscribeParams
                                       subscriptionEstablished:subscriptionEstablishedHandler
                                                 reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     reportHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}
+ (void)readAttributeInstantaneousLineCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                              completionHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInstantaneousLineCurrentWithClusterStateCache:attributeCacheContainer.realContainer
                                                            endpoint:endpoint
                                                               queue:queue
                                                          completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                              // Cast is safe because subclass does not add any selectors.
                                                              completionHandler(static_cast<NSNumber *>(value), error);
                                                          }];
}

- (void)readAttributeInstantaneousActiveCurrentWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    [self readAttributeInstantaneousActiveCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeInstantaneousActiveCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                                             params:(MTRSubscribeParams * _Nullable)params
                                            subscriptionEstablished:
                                                (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                      reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeInstantaneousActiveCurrentWithParams:subscribeParams
                                         subscriptionEstablished:subscriptionEstablishedHandler
                                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       reportHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}
+ (void)readAttributeInstantaneousActiveCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                         endpoint:(NSNumber *)endpoint
                                                            queue:(dispatch_queue_t)queue
                                                completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    [self readAttributeInstantaneousActiveCurrentWithClusterStateCache:attributeCacheContainer.realContainer
                                                              endpoint:endpoint
                                                                 queue:queue
                                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                // Cast is safe because subclass does not add any selectors.
                                                                completionHandler(static_cast<NSNumber *>(value), error);
                                                            }];
}

- (void)readAttributeInstantaneousReactiveCurrentWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completionHandler
{
    [self readAttributeInstantaneousReactiveCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeInstantaneousReactiveCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                                               params:(MTRSubscribeParams * _Nullable)params
                                              subscriptionEstablished:
                                                  (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                        reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeInstantaneousReactiveCurrentWithParams:subscribeParams
                                           subscriptionEstablished:subscriptionEstablishedHandler
                                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         reportHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}
+ (void)readAttributeInstantaneousReactiveCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                           endpoint:(NSNumber *)endpoint
                                                              queue:(dispatch_queue_t)queue
                                                  completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    [self readAttributeInstantaneousReactiveCurrentWithClusterStateCache:attributeCacheContainer.realContainer
                                                                endpoint:endpoint
                                                                   queue:queue
                                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                  // Cast is safe because subclass does not add any selectors.
                                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                                              }];
}

- (void)readAttributeInstantaneousPowerWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    [self readAttributeInstantaneousPowerWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeInstantaneousPowerWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:
                                        (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeInstantaneousPowerWithParams:subscribeParams
                                 subscriptionEstablished:subscriptionEstablishedHandler
                                           reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               reportHandler(static_cast<NSNumber *>(value), error);
                                           }];
}
+ (void)readAttributeInstantaneousPowerWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInstantaneousPowerWithClusterStateCache:attributeCacheContainer.realContainer
                                                      endpoint:endpoint
                                                         queue:queue
                                                    completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                        // Cast is safe because subclass does not add any selectors.
                                                        completionHandler(static_cast<NSNumber *>(value), error);
                                                    }];
}

- (void)readAttributeRmsVoltageWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsVoltageWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRmsVoltageWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRmsVoltageWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeRmsVoltageWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsVoltageWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeRmsVoltageMinWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsVoltageMinWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRmsVoltageMinWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRmsVoltageMinWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributeRmsVoltageMinWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsVoltageMinWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributeRmsVoltageMaxWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsVoltageMaxWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRmsVoltageMaxWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRmsVoltageMaxWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributeRmsVoltageMaxWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsVoltageMaxWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributeRmsCurrentWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRmsCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRmsCurrentWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeRmsCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsCurrentWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeRmsCurrentMinWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsCurrentMinWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRmsCurrentMinWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRmsCurrentMinWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributeRmsCurrentMinWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsCurrentMinWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributeRmsCurrentMaxWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsCurrentMaxWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRmsCurrentMaxWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRmsCurrentMaxWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributeRmsCurrentMaxWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsCurrentMaxWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributeActivePowerWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeActivePowerWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeActivePowerWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeActivePowerWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSNumber *>(value), error);
                                    }];
}
+ (void)readAttributeActivePowerWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeActivePowerWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                             }];
}

- (void)readAttributeActivePowerMinWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeActivePowerMinWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeActivePowerMinWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeActivePowerMinWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSNumber *>(value), error);
                                       }];
}
+ (void)readAttributeActivePowerMinWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeActivePowerMinWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSNumber *>(value), error);
                                                }];
}

- (void)readAttributeActivePowerMaxWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeActivePowerMaxWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeActivePowerMaxWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeActivePowerMaxWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSNumber *>(value), error);
                                       }];
}
+ (void)readAttributeActivePowerMaxWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeActivePowerMaxWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSNumber *>(value), error);
                                                }];
}

- (void)readAttributeReactivePowerWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeReactivePowerWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeReactivePowerWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeReactivePowerWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributeReactivePowerWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeReactivePowerWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributeApparentPowerWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeApparentPowerWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeApparentPowerWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeApparentPowerWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributeApparentPowerWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeApparentPowerWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributePowerFactorWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePowerFactorWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributePowerFactorWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePowerFactorWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSNumber *>(value), error);
                                    }];
}
+ (void)readAttributePowerFactorWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePowerFactorWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                             }];
}

- (void)readAttributeAverageRmsVoltageMeasurementPeriodWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                 NSError * _Nullable error))completionHandler
{
    [self readAttributeAverageRmsVoltageMeasurementPeriodWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeAverageRmsVoltageMeasurementPeriodWithValue:(NSNumber * _Nonnull)value
                                                completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeAverageRmsVoltageMeasurementPeriodWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeAverageRmsVoltageMeasurementPeriodWithValue:(NSNumber * _Nonnull)value
                                                           params:(MTRWriteParams * _Nullable)params
                                                completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeAverageRmsVoltageMeasurementPeriodWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeAverageRmsVoltageMeasurementPeriodWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                     params:(MTRSubscribeParams * _Nullable)params
                                                    subscriptionEstablished:
                                                        (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                              reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAverageRmsVoltageMeasurementPeriodWithParams:subscribeParams
                                                 subscriptionEstablished:subscriptionEstablishedHandler
                                                           reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                               // Cast is safe because subclass does not add any selectors.
                                                               reportHandler(static_cast<NSNumber *>(value), error);
                                                           }];
}
+ (void)readAttributeAverageRmsVoltageMeasurementPeriodWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                                 endpoint:(NSNumber *)endpoint
                                                                    queue:(dispatch_queue_t)queue
                                                        completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeAverageRmsVoltageMeasurementPeriodWithClusterStateCache:attributeCacheContainer.realContainer
                                                                      endpoint:endpoint
                                                                         queue:queue
                                                                    completion:^(
                                                                        NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                        // Cast is safe because subclass does not add any selectors.
                                                                        completionHandler(static_cast<NSNumber *>(value), error);
                                                                    }];
}

- (void)readAttributeAverageRmsUnderVoltageCounterWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))completionHandler
{
    [self readAttributeAverageRmsUnderVoltageCounterWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeAverageRmsUnderVoltageCounterWithValue:(NSNumber * _Nonnull)value
                                           completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeAverageRmsUnderVoltageCounterWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeAverageRmsUnderVoltageCounterWithValue:(NSNumber * _Nonnull)value
                                                      params:(MTRWriteParams * _Nullable)params
                                           completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeAverageRmsUnderVoltageCounterWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeAverageRmsUnderVoltageCounterWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                params:(MTRSubscribeParams * _Nullable)params
                                               subscriptionEstablished:
                                                   (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                         reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAverageRmsUnderVoltageCounterWithParams:subscribeParams
                                            subscriptionEstablished:subscriptionEstablishedHandler
                                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          reportHandler(static_cast<NSNumber *>(value), error);
                                                      }];
}
+ (void)readAttributeAverageRmsUnderVoltageCounterWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                            endpoint:(NSNumber *)endpoint
                                                               queue:(dispatch_queue_t)queue
                                                   completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    [self readAttributeAverageRmsUnderVoltageCounterWithClusterStateCache:attributeCacheContainer.realContainer
                                                                 endpoint:endpoint
                                                                    queue:queue
                                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                   // Cast is safe because subclass does not add any selectors.
                                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                                               }];
}

- (void)readAttributeRmsExtremeOverVoltagePeriodWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsExtremeOverVoltagePeriodWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeRmsExtremeOverVoltagePeriodWithValue:(NSNumber * _Nonnull)value
                                         completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeRmsExtremeOverVoltagePeriodWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeRmsExtremeOverVoltagePeriodWithValue:(NSNumber * _Nonnull)value
                                                    params:(MTRWriteParams * _Nullable)params
                                         completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeRmsExtremeOverVoltagePeriodWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeRmsExtremeOverVoltagePeriodWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                                              params:(MTRSubscribeParams * _Nullable)params
                                             subscriptionEstablished:
                                                 (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                       reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRmsExtremeOverVoltagePeriodWithParams:subscribeParams
                                          subscriptionEstablished:subscriptionEstablishedHandler
                                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                        // Cast is safe because subclass does not add any selectors.
                                                        reportHandler(static_cast<NSNumber *>(value), error);
                                                    }];
}
+ (void)readAttributeRmsExtremeOverVoltagePeriodWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                          endpoint:(NSNumber *)endpoint
                                                             queue:(dispatch_queue_t)queue
                                                 completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsExtremeOverVoltagePeriodWithClusterStateCache:attributeCacheContainer.realContainer
                                                               endpoint:endpoint
                                                                  queue:queue
                                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                 // Cast is safe because subclass does not add any selectors.
                                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                                             }];
}

- (void)readAttributeRmsExtremeUnderVoltagePeriodWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsExtremeUnderVoltagePeriodWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeRmsExtremeUnderVoltagePeriodWithValue:(NSNumber * _Nonnull)value
                                          completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeRmsExtremeUnderVoltagePeriodWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeRmsExtremeUnderVoltagePeriodWithValue:(NSNumber * _Nonnull)value
                                                     params:(MTRWriteParams * _Nullable)params
                                          completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeRmsExtremeUnderVoltagePeriodWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeRmsExtremeUnderVoltagePeriodWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                                               params:(MTRSubscribeParams * _Nullable)params
                                              subscriptionEstablished:
                                                  (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                        reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRmsExtremeUnderVoltagePeriodWithParams:subscribeParams
                                           subscriptionEstablished:subscriptionEstablishedHandler
                                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         reportHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}
+ (void)readAttributeRmsExtremeUnderVoltagePeriodWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                           endpoint:(NSNumber *)endpoint
                                                              queue:(dispatch_queue_t)queue
                                                  completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsExtremeUnderVoltagePeriodWithClusterStateCache:attributeCacheContainer.realContainer
                                                                endpoint:endpoint
                                                                   queue:queue
                                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                  // Cast is safe because subclass does not add any selectors.
                                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                                              }];
}

- (void)readAttributeRmsVoltageSagPeriodWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsVoltageSagPeriodWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeRmsVoltageSagPeriodWithValue:(NSNumber * _Nonnull)value
                                 completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeRmsVoltageSagPeriodWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeRmsVoltageSagPeriodWithValue:(NSNumber * _Nonnull)value
                                            params:(MTRWriteParams * _Nullable)params
                                 completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeRmsVoltageSagPeriodWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeRmsVoltageSagPeriodWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRmsVoltageSagPeriodWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSNumber *>(value), error);
                                            }];
}
+ (void)readAttributeRmsVoltageSagPeriodWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsVoltageSagPeriodWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}

- (void)readAttributeRmsVoltageSwellPeriodWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsVoltageSwellPeriodWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeRmsVoltageSwellPeriodWithValue:(NSNumber * _Nonnull)value
                                   completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeRmsVoltageSwellPeriodWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeRmsVoltageSwellPeriodWithValue:(NSNumber * _Nonnull)value
                                              params:(MTRWriteParams * _Nullable)params
                                   completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeRmsVoltageSwellPeriodWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeRmsVoltageSwellPeriodWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRmsVoltageSwellPeriodWithParams:subscribeParams
                                    subscriptionEstablished:subscriptionEstablishedHandler
                                              reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  reportHandler(static_cast<NSNumber *>(value), error);
                                              }];
}
+ (void)readAttributeRmsVoltageSwellPeriodWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsVoltageSwellPeriodWithClusterStateCache:attributeCacheContainer.realContainer
                                                         endpoint:endpoint
                                                            queue:queue
                                                       completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                           // Cast is safe because subclass does not add any selectors.
                                                           completionHandler(static_cast<NSNumber *>(value), error);
                                                       }];
}

- (void)readAttributeAcVoltageMultiplierWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcVoltageMultiplierWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeAcVoltageMultiplierWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcVoltageMultiplierWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSNumber *>(value), error);
                                            }];
}
+ (void)readAttributeAcVoltageMultiplierWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcVoltageMultiplierWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}

- (void)readAttributeAcVoltageDivisorWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeAcVoltageDivisorWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)
    subscribeAttributeAcVoltageDivisorWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcVoltageDivisorWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributeAcVoltageDivisorWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcVoltageDivisorWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeAcCurrentMultiplierWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcCurrentMultiplierWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeAcCurrentMultiplierWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcCurrentMultiplierWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSNumber *>(value), error);
                                            }];
}
+ (void)readAttributeAcCurrentMultiplierWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcCurrentMultiplierWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}

- (void)readAttributeAcCurrentDivisorWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeAcCurrentDivisorWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)
    subscribeAttributeAcCurrentDivisorWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcCurrentDivisorWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributeAcCurrentDivisorWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcCurrentDivisorWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeAcPowerMultiplierWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeAcPowerMultiplierWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeAcPowerMultiplierWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcPowerMultiplierWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSNumber *>(value), error);
                                          }];
}
+ (void)readAttributeAcPowerMultiplierWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcPowerMultiplierWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}

- (void)readAttributeAcPowerDivisorWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeAcPowerDivisorWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeAcPowerDivisorWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcPowerDivisorWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSNumber *>(value), error);
                                       }];
}
+ (void)readAttributeAcPowerDivisorWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcPowerDivisorWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSNumber *>(value), error);
                                                }];
}

- (void)readAttributeOverloadAlarmsMaskWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    [self readAttributeOverloadAlarmsMaskWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeOverloadAlarmsMaskWithValue:(NSNumber * _Nonnull)value
                                completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeOverloadAlarmsMaskWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeOverloadAlarmsMaskWithValue:(NSNumber * _Nonnull)value
                                           params:(MTRWriteParams * _Nullable)params
                                completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeOverloadAlarmsMaskWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeOverloadAlarmsMaskWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:
                                        (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeOverloadAlarmsMaskWithParams:subscribeParams
                                 subscriptionEstablished:subscriptionEstablishedHandler
                                           reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               reportHandler(static_cast<NSNumber *>(value), error);
                                           }];
}
+ (void)readAttributeOverloadAlarmsMaskWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOverloadAlarmsMaskWithClusterStateCache:attributeCacheContainer.realContainer
                                                      endpoint:endpoint
                                                         queue:queue
                                                    completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                        // Cast is safe because subclass does not add any selectors.
                                                        completionHandler(static_cast<NSNumber *>(value), error);
                                                    }];
}

- (void)readAttributeVoltageOverloadWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeVoltageOverloadWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeVoltageOverloadWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeVoltageOverloadWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeVoltageOverloadWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeVoltageOverloadWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (void)readAttributeCurrentOverloadWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentOverloadWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeCurrentOverloadWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeCurrentOverloadWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeCurrentOverloadWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCurrentOverloadWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (void)readAttributeAcOverloadAlarmsMaskWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeAcOverloadAlarmsMaskWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeAcOverloadAlarmsMaskWithValue:(NSNumber * _Nonnull)value
                                  completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeAcOverloadAlarmsMaskWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeAcOverloadAlarmsMaskWithValue:(NSNumber * _Nonnull)value
                                             params:(MTRWriteParams * _Nullable)params
                                  completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeAcOverloadAlarmsMaskWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeAcOverloadAlarmsMaskWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcOverloadAlarmsMaskWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSNumber *>(value), error);
                                             }];
}
+ (void)readAttributeAcOverloadAlarmsMaskWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcOverloadAlarmsMaskWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSNumber *>(value), error);
                                                      }];
}

- (void)readAttributeAcVoltageOverloadWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeAcVoltageOverloadWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeAcVoltageOverloadWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcVoltageOverloadWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSNumber *>(value), error);
                                          }];
}
+ (void)readAttributeAcVoltageOverloadWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcVoltageOverloadWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}

- (void)readAttributeAcCurrentOverloadWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeAcCurrentOverloadWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeAcCurrentOverloadWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcCurrentOverloadWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSNumber *>(value), error);
                                          }];
}
+ (void)readAttributeAcCurrentOverloadWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcCurrentOverloadWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}

- (void)readAttributeAcActivePowerOverloadWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    [self readAttributeAcActivePowerOverloadWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeAcActivePowerOverloadWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcActivePowerOverloadWithParams:subscribeParams
                                    subscriptionEstablished:subscriptionEstablishedHandler
                                              reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  reportHandler(static_cast<NSNumber *>(value), error);
                                              }];
}
+ (void)readAttributeAcActivePowerOverloadWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcActivePowerOverloadWithClusterStateCache:attributeCacheContainer.realContainer
                                                         endpoint:endpoint
                                                            queue:queue
                                                       completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                           // Cast is safe because subclass does not add any selectors.
                                                           completionHandler(static_cast<NSNumber *>(value), error);
                                                       }];
}

- (void)readAttributeAcReactivePowerOverloadWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    [self readAttributeAcReactivePowerOverloadWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeAcReactivePowerOverloadWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                                          params:(MTRSubscribeParams * _Nullable)params
                                         subscriptionEstablished:
                                             (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                   reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcReactivePowerOverloadWithParams:subscribeParams
                                      subscriptionEstablished:subscriptionEstablishedHandler
                                                reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    reportHandler(static_cast<NSNumber *>(value), error);
                                                }];
}
+ (void)readAttributeAcReactivePowerOverloadWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                             completionHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcReactivePowerOverloadWithClusterStateCache:attributeCacheContainer.realContainer
                                                           endpoint:endpoint
                                                              queue:queue
                                                         completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                             // Cast is safe because subclass does not add any selectors.
                                                             completionHandler(static_cast<NSNumber *>(value), error);
                                                         }];
}

- (void)readAttributeAverageRmsOverVoltageWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    [self readAttributeAverageRmsOverVoltageWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeAverageRmsOverVoltageWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAverageRmsOverVoltageWithParams:subscribeParams
                                    subscriptionEstablished:subscriptionEstablishedHandler
                                              reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  reportHandler(static_cast<NSNumber *>(value), error);
                                              }];
}
+ (void)readAttributeAverageRmsOverVoltageWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAverageRmsOverVoltageWithClusterStateCache:attributeCacheContainer.realContainer
                                                         endpoint:endpoint
                                                            queue:queue
                                                       completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                           // Cast is safe because subclass does not add any selectors.
                                                           completionHandler(static_cast<NSNumber *>(value), error);
                                                       }];
}

- (void)readAttributeAverageRmsUnderVoltageWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    [self readAttributeAverageRmsUnderVoltageWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeAverageRmsUnderVoltageWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                                         params:(MTRSubscribeParams * _Nullable)params
                                        subscriptionEstablished:
                                            (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAverageRmsUnderVoltageWithParams:subscribeParams
                                     subscriptionEstablished:subscriptionEstablishedHandler
                                               reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   reportHandler(static_cast<NSNumber *>(value), error);
                                               }];
}
+ (void)readAttributeAverageRmsUnderVoltageWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                            completionHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAverageRmsUnderVoltageWithClusterStateCache:attributeCacheContainer.realContainer
                                                          endpoint:endpoint
                                                             queue:queue
                                                        completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                            // Cast is safe because subclass does not add any selectors.
                                                            completionHandler(static_cast<NSNumber *>(value), error);
                                                        }];
}

- (void)readAttributeRmsExtremeOverVoltageWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsExtremeOverVoltageWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRmsExtremeOverVoltageWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRmsExtremeOverVoltageWithParams:subscribeParams
                                    subscriptionEstablished:subscriptionEstablishedHandler
                                              reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  reportHandler(static_cast<NSNumber *>(value), error);
                                              }];
}
+ (void)readAttributeRmsExtremeOverVoltageWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsExtremeOverVoltageWithClusterStateCache:attributeCacheContainer.realContainer
                                                         endpoint:endpoint
                                                            queue:queue
                                                       completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                           // Cast is safe because subclass does not add any selectors.
                                                           completionHandler(static_cast<NSNumber *>(value), error);
                                                       }];
}

- (void)readAttributeRmsExtremeUnderVoltageWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsExtremeUnderVoltageWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRmsExtremeUnderVoltageWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                                         params:(MTRSubscribeParams * _Nullable)params
                                        subscriptionEstablished:
                                            (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRmsExtremeUnderVoltageWithParams:subscribeParams
                                     subscriptionEstablished:subscriptionEstablishedHandler
                                               reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   reportHandler(static_cast<NSNumber *>(value), error);
                                               }];
}
+ (void)readAttributeRmsExtremeUnderVoltageWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                            completionHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsExtremeUnderVoltageWithClusterStateCache:attributeCacheContainer.realContainer
                                                          endpoint:endpoint
                                                             queue:queue
                                                        completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                            // Cast is safe because subclass does not add any selectors.
                                                            completionHandler(static_cast<NSNumber *>(value), error);
                                                        }];
}

- (void)readAttributeRmsVoltageSagWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsVoltageSagWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRmsVoltageSagWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRmsVoltageSagWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributeRmsVoltageSagWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsVoltageSagWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributeRmsVoltageSwellWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsVoltageSwellWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRmsVoltageSwellWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRmsVoltageSwellWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeRmsVoltageSwellWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsVoltageSwellWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (void)readAttributeLineCurrentPhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeLineCurrentPhaseBWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeLineCurrentPhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeLineCurrentPhaseBWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSNumber *>(value), error);
                                          }];
}
+ (void)readAttributeLineCurrentPhaseBWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLineCurrentPhaseBWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}

- (void)readAttributeActiveCurrentPhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeActiveCurrentPhaseBWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeActiveCurrentPhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeActiveCurrentPhaseBWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSNumber *>(value), error);
                                            }];
}
+ (void)readAttributeActiveCurrentPhaseBWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeActiveCurrentPhaseBWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}

- (void)readAttributeReactiveCurrentPhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    [self readAttributeReactiveCurrentPhaseBWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeReactiveCurrentPhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeReactiveCurrentPhaseBWithParams:subscribeParams
                                    subscriptionEstablished:subscriptionEstablishedHandler
                                              reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  reportHandler(static_cast<NSNumber *>(value), error);
                                              }];
}
+ (void)readAttributeReactiveCurrentPhaseBWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeReactiveCurrentPhaseBWithClusterStateCache:attributeCacheContainer.realContainer
                                                         endpoint:endpoint
                                                            queue:queue
                                                       completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                           // Cast is safe because subclass does not add any selectors.
                                                           completionHandler(static_cast<NSNumber *>(value), error);
                                                       }];
}

- (void)readAttributeRmsVoltagePhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsVoltagePhaseBWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)
    subscribeAttributeRmsVoltagePhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRmsVoltagePhaseBWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributeRmsVoltagePhaseBWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsVoltagePhaseBWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeRmsVoltageMinPhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsVoltageMinPhaseBWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRmsVoltageMinPhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRmsVoltageMinPhaseBWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSNumber *>(value), error);
                                            }];
}
+ (void)readAttributeRmsVoltageMinPhaseBWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsVoltageMinPhaseBWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}

- (void)readAttributeRmsVoltageMaxPhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsVoltageMaxPhaseBWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRmsVoltageMaxPhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRmsVoltageMaxPhaseBWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSNumber *>(value), error);
                                            }];
}
+ (void)readAttributeRmsVoltageMaxPhaseBWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsVoltageMaxPhaseBWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}

- (void)readAttributeRmsCurrentPhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsCurrentPhaseBWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)
    subscribeAttributeRmsCurrentPhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRmsCurrentPhaseBWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributeRmsCurrentPhaseBWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsCurrentPhaseBWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeRmsCurrentMinPhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsCurrentMinPhaseBWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRmsCurrentMinPhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRmsCurrentMinPhaseBWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSNumber *>(value), error);
                                            }];
}
+ (void)readAttributeRmsCurrentMinPhaseBWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsCurrentMinPhaseBWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}

- (void)readAttributeRmsCurrentMaxPhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsCurrentMaxPhaseBWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRmsCurrentMaxPhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRmsCurrentMaxPhaseBWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSNumber *>(value), error);
                                            }];
}
+ (void)readAttributeRmsCurrentMaxPhaseBWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsCurrentMaxPhaseBWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}

- (void)readAttributeActivePowerPhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeActivePowerPhaseBWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeActivePowerPhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeActivePowerPhaseBWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSNumber *>(value), error);
                                          }];
}
+ (void)readAttributeActivePowerPhaseBWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeActivePowerPhaseBWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}

- (void)readAttributeActivePowerMinPhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeActivePowerMinPhaseBWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeActivePowerMinPhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeActivePowerMinPhaseBWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSNumber *>(value), error);
                                             }];
}
+ (void)readAttributeActivePowerMinPhaseBWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeActivePowerMinPhaseBWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSNumber *>(value), error);
                                                      }];
}

- (void)readAttributeActivePowerMaxPhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeActivePowerMaxPhaseBWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeActivePowerMaxPhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeActivePowerMaxPhaseBWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSNumber *>(value), error);
                                             }];
}
+ (void)readAttributeActivePowerMaxPhaseBWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeActivePowerMaxPhaseBWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSNumber *>(value), error);
                                                      }];
}

- (void)readAttributeReactivePowerPhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeReactivePowerPhaseBWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeReactivePowerPhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeReactivePowerPhaseBWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSNumber *>(value), error);
                                            }];
}
+ (void)readAttributeReactivePowerPhaseBWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeReactivePowerPhaseBWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}

- (void)readAttributeApparentPowerPhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeApparentPowerPhaseBWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeApparentPowerPhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeApparentPowerPhaseBWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSNumber *>(value), error);
                                            }];
}
+ (void)readAttributeApparentPowerPhaseBWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeApparentPowerPhaseBWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}

- (void)readAttributePowerFactorPhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributePowerFactorPhaseBWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributePowerFactorPhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePowerFactorPhaseBWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSNumber *>(value), error);
                                          }];
}
+ (void)readAttributePowerFactorPhaseBWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePowerFactorPhaseBWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}

- (void)readAttributeAverageRmsVoltageMeasurementPeriodPhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                       NSError * _Nullable error))completionHandler
{
    [self readAttributeAverageRmsVoltageMeasurementPeriodPhaseBWithCompletion:^(
        NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeAverageRmsVoltageMeasurementPeriodPhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                           params:(MTRSubscribeParams * _Nullable)params
                                                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)
                                                                                      subscriptionEstablishedHandler
                                                                    reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                      NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAverageRmsVoltageMeasurementPeriodPhaseBWithParams:subscribeParams
                                                       subscriptionEstablished:subscriptionEstablishedHandler
                                                                 reportHandler:^(
                                                                     NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                     // Cast is safe because subclass does not add any selectors.
                                                                     reportHandler(static_cast<NSNumber *>(value), error);
                                                                 }];
}
+ (void)readAttributeAverageRmsVoltageMeasurementPeriodPhaseBWithAttributeCache:
            (MTRAttributeCacheContainer *)attributeCacheContainer
                                                                       endpoint:(NSNumber *)endpoint
                                                                          queue:(dispatch_queue_t)queue
                                                              completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                    NSError * _Nullable error))completionHandler
{
    [self readAttributeAverageRmsVoltageMeasurementPeriodPhaseBWithClusterStateCache:attributeCacheContainer.realContainer
                                                                            endpoint:endpoint
                                                                               queue:queue
                                                                          completion:^(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error) {
                                                                              // Cast is safe because subclass does not add any
                                                                              // selectors.
                                                                              completionHandler(
                                                                                  static_cast<NSNumber *>(value), error);
                                                                          }];
}

- (void)readAttributeAverageRmsOverVoltageCounterPhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                 NSError * _Nullable error))completionHandler
{
    [self readAttributeAverageRmsOverVoltageCounterPhaseBWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeAverageRmsOverVoltageCounterPhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                     params:(MTRSubscribeParams * _Nullable)params
                                                    subscriptionEstablished:
                                                        (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                              reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAverageRmsOverVoltageCounterPhaseBWithParams:subscribeParams
                                                 subscriptionEstablished:subscriptionEstablishedHandler
                                                           reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                               // Cast is safe because subclass does not add any selectors.
                                                               reportHandler(static_cast<NSNumber *>(value), error);
                                                           }];
}
+ (void)readAttributeAverageRmsOverVoltageCounterPhaseBWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                                 endpoint:(NSNumber *)endpoint
                                                                    queue:(dispatch_queue_t)queue
                                                        completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeAverageRmsOverVoltageCounterPhaseBWithClusterStateCache:attributeCacheContainer.realContainer
                                                                      endpoint:endpoint
                                                                         queue:queue
                                                                    completion:^(
                                                                        NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                        // Cast is safe because subclass does not add any selectors.
                                                                        completionHandler(static_cast<NSNumber *>(value), error);
                                                                    }];
}

- (void)readAttributeAverageRmsUnderVoltageCounterPhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAverageRmsUnderVoltageCounterPhaseBWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeAverageRmsUnderVoltageCounterPhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                      params:(MTRSubscribeParams * _Nullable)params
                                                     subscriptionEstablished:
                                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                               reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                 NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAverageRmsUnderVoltageCounterPhaseBWithParams:subscribeParams
                                                  subscriptionEstablished:subscriptionEstablishedHandler
                                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                // Cast is safe because subclass does not add any selectors.
                                                                reportHandler(static_cast<NSNumber *>(value), error);
                                                            }];
}
+ (void)readAttributeAverageRmsUnderVoltageCounterPhaseBWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                                  endpoint:(NSNumber *)endpoint
                                                                     queue:(dispatch_queue_t)queue
                                                         completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeAverageRmsUnderVoltageCounterPhaseBWithClusterStateCache:attributeCacheContainer.realContainer
                                                                       endpoint:endpoint
                                                                          queue:queue
                                                                     completion:^(
                                                                         NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                         // Cast is safe because subclass does not add any
                                                                         // selectors.
                                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                                     }];
}

- (void)readAttributeRmsExtremeOverVoltagePeriodPhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsExtremeOverVoltagePeriodPhaseBWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRmsExtremeOverVoltagePeriodPhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                    params:(MTRSubscribeParams * _Nullable)params
                                                   subscriptionEstablished:
                                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                             reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                               NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRmsExtremeOverVoltagePeriodPhaseBWithParams:subscribeParams
                                                subscriptionEstablished:subscriptionEstablishedHandler
                                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                              // Cast is safe because subclass does not add any selectors.
                                                              reportHandler(static_cast<NSNumber *>(value), error);
                                                          }];
}
+ (void)readAttributeRmsExtremeOverVoltagePeriodPhaseBWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                                endpoint:(NSNumber *)endpoint
                                                                   queue:(dispatch_queue_t)queue
                                                       completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsExtremeOverVoltagePeriodPhaseBWithClusterStateCache:attributeCacheContainer.realContainer
                                                                     endpoint:endpoint
                                                                        queue:queue
                                                                   completion:^(
                                                                       NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                       // Cast is safe because subclass does not add any selectors.
                                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                                   }];
}

- (void)readAttributeRmsExtremeUnderVoltagePeriodPhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                 NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsExtremeUnderVoltagePeriodPhaseBWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRmsExtremeUnderVoltagePeriodPhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                     params:(MTRSubscribeParams * _Nullable)params
                                                    subscriptionEstablished:
                                                        (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                              reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRmsExtremeUnderVoltagePeriodPhaseBWithParams:subscribeParams
                                                 subscriptionEstablished:subscriptionEstablishedHandler
                                                           reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                               // Cast is safe because subclass does not add any selectors.
                                                               reportHandler(static_cast<NSNumber *>(value), error);
                                                           }];
}
+ (void)readAttributeRmsExtremeUnderVoltagePeriodPhaseBWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                                 endpoint:(NSNumber *)endpoint
                                                                    queue:(dispatch_queue_t)queue
                                                        completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsExtremeUnderVoltagePeriodPhaseBWithClusterStateCache:attributeCacheContainer.realContainer
                                                                      endpoint:endpoint
                                                                         queue:queue
                                                                    completion:^(
                                                                        NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                        // Cast is safe because subclass does not add any selectors.
                                                                        completionHandler(static_cast<NSNumber *>(value), error);
                                                                    }];
}

- (void)readAttributeRmsVoltageSagPeriodPhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsVoltageSagPeriodPhaseBWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRmsVoltageSagPeriodPhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                                            params:(MTRSubscribeParams * _Nullable)params
                                           subscriptionEstablished:
                                               (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                     reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRmsVoltageSagPeriodPhaseBWithParams:subscribeParams
                                        subscriptionEstablished:subscriptionEstablishedHandler
                                                  reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      reportHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}
+ (void)readAttributeRmsVoltageSagPeriodPhaseBWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                               completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsVoltageSagPeriodPhaseBWithClusterStateCache:attributeCacheContainer.realContainer
                                                             endpoint:endpoint
                                                                queue:queue
                                                           completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                               // Cast is safe because subclass does not add any selectors.
                                                               completionHandler(static_cast<NSNumber *>(value), error);
                                                           }];
}

- (void)readAttributeRmsVoltageSwellPeriodPhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsVoltageSwellPeriodPhaseBWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRmsVoltageSwellPeriodPhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                                              params:(MTRSubscribeParams * _Nullable)params
                                             subscriptionEstablished:
                                                 (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                       reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRmsVoltageSwellPeriodPhaseBWithParams:subscribeParams
                                          subscriptionEstablished:subscriptionEstablishedHandler
                                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                        // Cast is safe because subclass does not add any selectors.
                                                        reportHandler(static_cast<NSNumber *>(value), error);
                                                    }];
}
+ (void)readAttributeRmsVoltageSwellPeriodPhaseBWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                          endpoint:(NSNumber *)endpoint
                                                             queue:(dispatch_queue_t)queue
                                                 completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsVoltageSwellPeriodPhaseBWithClusterStateCache:attributeCacheContainer.realContainer
                                                               endpoint:endpoint
                                                                  queue:queue
                                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                 // Cast is safe because subclass does not add any selectors.
                                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                                             }];
}

- (void)readAttributeLineCurrentPhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeLineCurrentPhaseCWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeLineCurrentPhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeLineCurrentPhaseCWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSNumber *>(value), error);
                                          }];
}
+ (void)readAttributeLineCurrentPhaseCWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLineCurrentPhaseCWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}

- (void)readAttributeActiveCurrentPhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeActiveCurrentPhaseCWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeActiveCurrentPhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeActiveCurrentPhaseCWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSNumber *>(value), error);
                                            }];
}
+ (void)readAttributeActiveCurrentPhaseCWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeActiveCurrentPhaseCWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}

- (void)readAttributeReactiveCurrentPhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    [self readAttributeReactiveCurrentPhaseCWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeReactiveCurrentPhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeReactiveCurrentPhaseCWithParams:subscribeParams
                                    subscriptionEstablished:subscriptionEstablishedHandler
                                              reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  reportHandler(static_cast<NSNumber *>(value), error);
                                              }];
}
+ (void)readAttributeReactiveCurrentPhaseCWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeReactiveCurrentPhaseCWithClusterStateCache:attributeCacheContainer.realContainer
                                                         endpoint:endpoint
                                                            queue:queue
                                                       completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                           // Cast is safe because subclass does not add any selectors.
                                                           completionHandler(static_cast<NSNumber *>(value), error);
                                                       }];
}

- (void)readAttributeRmsVoltagePhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsVoltagePhaseCWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)
    subscribeAttributeRmsVoltagePhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRmsVoltagePhaseCWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributeRmsVoltagePhaseCWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsVoltagePhaseCWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeRmsVoltageMinPhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsVoltageMinPhaseCWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRmsVoltageMinPhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRmsVoltageMinPhaseCWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSNumber *>(value), error);
                                            }];
}
+ (void)readAttributeRmsVoltageMinPhaseCWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsVoltageMinPhaseCWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}

- (void)readAttributeRmsVoltageMaxPhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsVoltageMaxPhaseCWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRmsVoltageMaxPhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRmsVoltageMaxPhaseCWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSNumber *>(value), error);
                                            }];
}
+ (void)readAttributeRmsVoltageMaxPhaseCWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsVoltageMaxPhaseCWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}

- (void)readAttributeRmsCurrentPhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsCurrentPhaseCWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)
    subscribeAttributeRmsCurrentPhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRmsCurrentPhaseCWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributeRmsCurrentPhaseCWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsCurrentPhaseCWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeRmsCurrentMinPhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsCurrentMinPhaseCWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRmsCurrentMinPhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRmsCurrentMinPhaseCWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSNumber *>(value), error);
                                            }];
}
+ (void)readAttributeRmsCurrentMinPhaseCWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsCurrentMinPhaseCWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}

- (void)readAttributeRmsCurrentMaxPhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsCurrentMaxPhaseCWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRmsCurrentMaxPhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRmsCurrentMaxPhaseCWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSNumber *>(value), error);
                                            }];
}
+ (void)readAttributeRmsCurrentMaxPhaseCWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsCurrentMaxPhaseCWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}

- (void)readAttributeActivePowerPhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeActivePowerPhaseCWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeActivePowerPhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeActivePowerPhaseCWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSNumber *>(value), error);
                                          }];
}
+ (void)readAttributeActivePowerPhaseCWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeActivePowerPhaseCWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}

- (void)readAttributeActivePowerMinPhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeActivePowerMinPhaseCWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeActivePowerMinPhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeActivePowerMinPhaseCWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSNumber *>(value), error);
                                             }];
}
+ (void)readAttributeActivePowerMinPhaseCWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeActivePowerMinPhaseCWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSNumber *>(value), error);
                                                      }];
}

- (void)readAttributeActivePowerMaxPhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeActivePowerMaxPhaseCWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeActivePowerMaxPhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeActivePowerMaxPhaseCWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSNumber *>(value), error);
                                             }];
}
+ (void)readAttributeActivePowerMaxPhaseCWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeActivePowerMaxPhaseCWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSNumber *>(value), error);
                                                      }];
}

- (void)readAttributeReactivePowerPhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeReactivePowerPhaseCWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeReactivePowerPhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeReactivePowerPhaseCWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSNumber *>(value), error);
                                            }];
}
+ (void)readAttributeReactivePowerPhaseCWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeReactivePowerPhaseCWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}

- (void)readAttributeApparentPowerPhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeApparentPowerPhaseCWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeApparentPowerPhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeApparentPowerPhaseCWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSNumber *>(value), error);
                                            }];
}
+ (void)readAttributeApparentPowerPhaseCWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeApparentPowerPhaseCWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}

- (void)readAttributePowerFactorPhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributePowerFactorPhaseCWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributePowerFactorPhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributePowerFactorPhaseCWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSNumber *>(value), error);
                                          }];
}
+ (void)readAttributePowerFactorPhaseCWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributePowerFactorPhaseCWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}

- (void)readAttributeAverageRmsVoltageMeasurementPeriodPhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                       NSError * _Nullable error))completionHandler
{
    [self readAttributeAverageRmsVoltageMeasurementPeriodPhaseCWithCompletion:^(
        NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeAverageRmsVoltageMeasurementPeriodPhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                           params:(MTRSubscribeParams * _Nullable)params
                                                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)
                                                                                      subscriptionEstablishedHandler
                                                                    reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                      NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAverageRmsVoltageMeasurementPeriodPhaseCWithParams:subscribeParams
                                                       subscriptionEstablished:subscriptionEstablishedHandler
                                                                 reportHandler:^(
                                                                     NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                     // Cast is safe because subclass does not add any selectors.
                                                                     reportHandler(static_cast<NSNumber *>(value), error);
                                                                 }];
}
+ (void)readAttributeAverageRmsVoltageMeasurementPeriodPhaseCWithAttributeCache:
            (MTRAttributeCacheContainer *)attributeCacheContainer
                                                                       endpoint:(NSNumber *)endpoint
                                                                          queue:(dispatch_queue_t)queue
                                                              completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                    NSError * _Nullable error))completionHandler
{
    [self readAttributeAverageRmsVoltageMeasurementPeriodPhaseCWithClusterStateCache:attributeCacheContainer.realContainer
                                                                            endpoint:endpoint
                                                                               queue:queue
                                                                          completion:^(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error) {
                                                                              // Cast is safe because subclass does not add any
                                                                              // selectors.
                                                                              completionHandler(
                                                                                  static_cast<NSNumber *>(value), error);
                                                                          }];
}

- (void)readAttributeAverageRmsOverVoltageCounterPhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                 NSError * _Nullable error))completionHandler
{
    [self readAttributeAverageRmsOverVoltageCounterPhaseCWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeAverageRmsOverVoltageCounterPhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                     params:(MTRSubscribeParams * _Nullable)params
                                                    subscriptionEstablished:
                                                        (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                              reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAverageRmsOverVoltageCounterPhaseCWithParams:subscribeParams
                                                 subscriptionEstablished:subscriptionEstablishedHandler
                                                           reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                               // Cast is safe because subclass does not add any selectors.
                                                               reportHandler(static_cast<NSNumber *>(value), error);
                                                           }];
}
+ (void)readAttributeAverageRmsOverVoltageCounterPhaseCWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                                 endpoint:(NSNumber *)endpoint
                                                                    queue:(dispatch_queue_t)queue
                                                        completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeAverageRmsOverVoltageCounterPhaseCWithClusterStateCache:attributeCacheContainer.realContainer
                                                                      endpoint:endpoint
                                                                         queue:queue
                                                                    completion:^(
                                                                        NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                        // Cast is safe because subclass does not add any selectors.
                                                                        completionHandler(static_cast<NSNumber *>(value), error);
                                                                    }];
}

- (void)readAttributeAverageRmsUnderVoltageCounterPhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAverageRmsUnderVoltageCounterPhaseCWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeAverageRmsUnderVoltageCounterPhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                      params:(MTRSubscribeParams * _Nullable)params
                                                     subscriptionEstablished:
                                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                               reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                 NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAverageRmsUnderVoltageCounterPhaseCWithParams:subscribeParams
                                                  subscriptionEstablished:subscriptionEstablishedHandler
                                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                // Cast is safe because subclass does not add any selectors.
                                                                reportHandler(static_cast<NSNumber *>(value), error);
                                                            }];
}
+ (void)readAttributeAverageRmsUnderVoltageCounterPhaseCWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                                  endpoint:(NSNumber *)endpoint
                                                                     queue:(dispatch_queue_t)queue
                                                         completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeAverageRmsUnderVoltageCounterPhaseCWithClusterStateCache:attributeCacheContainer.realContainer
                                                                       endpoint:endpoint
                                                                          queue:queue
                                                                     completion:^(
                                                                         NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                         // Cast is safe because subclass does not add any
                                                                         // selectors.
                                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                                     }];
}

- (void)readAttributeRmsExtremeOverVoltagePeriodPhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsExtremeOverVoltagePeriodPhaseCWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRmsExtremeOverVoltagePeriodPhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                    params:(MTRSubscribeParams * _Nullable)params
                                                   subscriptionEstablished:
                                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                             reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                               NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRmsExtremeOverVoltagePeriodPhaseCWithParams:subscribeParams
                                                subscriptionEstablished:subscriptionEstablishedHandler
                                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                              // Cast is safe because subclass does not add any selectors.
                                                              reportHandler(static_cast<NSNumber *>(value), error);
                                                          }];
}
+ (void)readAttributeRmsExtremeOverVoltagePeriodPhaseCWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                                endpoint:(NSNumber *)endpoint
                                                                   queue:(dispatch_queue_t)queue
                                                       completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsExtremeOverVoltagePeriodPhaseCWithClusterStateCache:attributeCacheContainer.realContainer
                                                                     endpoint:endpoint
                                                                        queue:queue
                                                                   completion:^(
                                                                       NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                       // Cast is safe because subclass does not add any selectors.
                                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                                   }];
}

- (void)readAttributeRmsExtremeUnderVoltagePeriodPhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                 NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsExtremeUnderVoltagePeriodPhaseCWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRmsExtremeUnderVoltagePeriodPhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                     params:(MTRSubscribeParams * _Nullable)params
                                                    subscriptionEstablished:
                                                        (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                              reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRmsExtremeUnderVoltagePeriodPhaseCWithParams:subscribeParams
                                                 subscriptionEstablished:subscriptionEstablishedHandler
                                                           reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                               // Cast is safe because subclass does not add any selectors.
                                                               reportHandler(static_cast<NSNumber *>(value), error);
                                                           }];
}
+ (void)readAttributeRmsExtremeUnderVoltagePeriodPhaseCWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                                 endpoint:(NSNumber *)endpoint
                                                                    queue:(dispatch_queue_t)queue
                                                        completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsExtremeUnderVoltagePeriodPhaseCWithClusterStateCache:attributeCacheContainer.realContainer
                                                                      endpoint:endpoint
                                                                         queue:queue
                                                                    completion:^(
                                                                        NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                        // Cast is safe because subclass does not add any selectors.
                                                                        completionHandler(static_cast<NSNumber *>(value), error);
                                                                    }];
}

- (void)readAttributeRmsVoltageSagPeriodPhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsVoltageSagPeriodPhaseCWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRmsVoltageSagPeriodPhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                                            params:(MTRSubscribeParams * _Nullable)params
                                           subscriptionEstablished:
                                               (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                     reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRmsVoltageSagPeriodPhaseCWithParams:subscribeParams
                                        subscriptionEstablished:subscriptionEstablishedHandler
                                                  reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      reportHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}
+ (void)readAttributeRmsVoltageSagPeriodPhaseCWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                               completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsVoltageSagPeriodPhaseCWithClusterStateCache:attributeCacheContainer.realContainer
                                                             endpoint:endpoint
                                                                queue:queue
                                                           completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                               // Cast is safe because subclass does not add any selectors.
                                                               completionHandler(static_cast<NSNumber *>(value), error);
                                                           }];
}

- (void)readAttributeRmsVoltageSwellPeriodPhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsVoltageSwellPeriodPhaseCWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeRmsVoltageSwellPeriodPhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                                              params:(MTRSubscribeParams * _Nullable)params
                                             subscriptionEstablished:
                                                 (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                       reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRmsVoltageSwellPeriodPhaseCWithParams:subscribeParams
                                          subscriptionEstablished:subscriptionEstablishedHandler
                                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                        // Cast is safe because subclass does not add any selectors.
                                                        reportHandler(static_cast<NSNumber *>(value), error);
                                                    }];
}
+ (void)readAttributeRmsVoltageSwellPeriodPhaseCWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                          endpoint:(NSNumber *)endpoint
                                                             queue:(dispatch_queue_t)queue
                                                 completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completionHandler
{
    [self readAttributeRmsVoltageSwellPeriodPhaseCWithClusterStateCache:attributeCacheContainer.realContainer
                                                               endpoint:endpoint
                                                                  queue:queue
                                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                 // Cast is safe because subclass does not add any selectors.
                                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                                             }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

@implementation MTRBaseClusterUnitTesting

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = [endpointID unsignedShortValue];
    }
    return self;
}

- (void)testWithCompletion:(MTRStatusCompletion)completion
{
    [self testWithParams:nil completion:completion];
}
- (void)testWithParams:(MTRUnitTestingClusterTestParams * _Nullable)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            UnitTesting::Commands::Test::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)testNotHandledWithCompletion:(MTRStatusCompletion)completion
{
    [self testNotHandledWithParams:nil completion:completion];
}
- (void)testNotHandledWithParams:(MTRUnitTestingClusterTestNotHandledParams * _Nullable)params
                      completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            UnitTesting::Commands::TestNotHandled::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)testSpecificWithCompletion:(void (^)(MTRUnitTestingClusterTestSpecificResponseParams * _Nullable data,
                                       NSError * _Nullable error))completion
{
    [self testSpecificWithParams:nil completion:completion];
}
- (void)testSpecificWithParams:(MTRUnitTestingClusterTestSpecificParams * _Nullable)params
                    completion:(void (^)(MTRUnitTestingClusterTestSpecificResponseParams * _Nullable data,
                                   NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRUnitTestingClusterTestSpecificResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            UnitTestingClusterTestSpecificResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRUnitTestingClusterTestSpecificResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            UnitTesting::Commands::TestSpecific::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)testUnknownCommandWithCompletion:(MTRStatusCompletion)completion
{
    [self testUnknownCommandWithParams:nil completion:completion];
}
- (void)testUnknownCommandWithParams:(MTRUnitTestingClusterTestUnknownCommandParams * _Nullable)params
                          completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            UnitTesting::Commands::TestUnknownCommand::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)testAddArgumentsWithParams:(MTRUnitTestingClusterTestAddArgumentsParams *)params
                        completion:(void (^)(MTRUnitTestingClusterTestAddArgumentsResponseParams * _Nullable data,
                                       NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRUnitTestingClusterTestAddArgumentsResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            UnitTestingClusterTestAddArgumentsResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRUnitTestingClusterTestAddArgumentsResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            UnitTesting::Commands::TestAddArguments::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.arg1 = params.arg1.unsignedCharValue;
            request.arg2 = params.arg2.unsignedCharValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)testSimpleArgumentRequestWithParams:(MTRUnitTestingClusterTestSimpleArgumentRequestParams *)params
                                 completion:(void (^)(MTRUnitTestingClusterTestSimpleArgumentResponseParams * _Nullable data,
                                                NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRUnitTestingClusterTestSimpleArgumentResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            UnitTestingClusterTestSimpleArgumentResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRUnitTestingClusterTestSimpleArgumentResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            UnitTesting::Commands::TestSimpleArgumentRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.arg1 = params.arg1.boolValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)testStructArrayArgumentRequestWithParams:(MTRUnitTestingClusterTestStructArrayArgumentRequestParams *)params
                                      completion:
                                          (void (^)(MTRUnitTestingClusterTestStructArrayArgumentResponseParams * _Nullable data,
                                              NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRUnitTestingClusterTestStructArrayArgumentResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            UnitTestingClusterTestStructArrayArgumentResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRUnitTestingClusterTestStructArrayArgumentResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            UnitTesting::Commands::TestStructArrayArgumentRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            {
                using ListType_0 = std::remove_reference_t<decltype(request.arg1)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (params.arg1.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(params.arg1.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < params.arg1.count; ++i_0) {
                        if (![params.arg1[i_0] isKindOfClass:[MTRUnitTestingClusterNestedStructList class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (MTRUnitTestingClusterNestedStructList *) params.arg1[i_0];
                        listHolder_0->mList[i_0].a = element_0.a.unsignedCharValue;
                        listHolder_0->mList[i_0].b = element_0.b.boolValue;
                        listHolder_0->mList[i_0].c.a = element_0.c.a.unsignedCharValue;
                        listHolder_0->mList[i_0].c.b = element_0.c.b.boolValue;
                        listHolder_0->mList[i_0].c.c = static_cast<std::remove_reference_t<decltype(listHolder_0->mList[i_0].c.c)>>(
                            element_0.c.c.unsignedCharValue);
                        listHolder_0->mList[i_0].c.d = [self asByteSpan:element_0.c.d];
                        listHolder_0->mList[i_0].c.e = [self asCharSpan:element_0.c.e];
                        listHolder_0->mList[i_0].c.f = static_cast<std::remove_reference_t<decltype(listHolder_0->mList[i_0].c.f)>>(
                            element_0.c.f.unsignedCharValue);
                        listHolder_0->mList[i_0].c.g = element_0.c.g.floatValue;
                        listHolder_0->mList[i_0].c.h = element_0.c.h.doubleValue;
                        {
                            using ListType_2 = std::remove_reference_t<decltype(listHolder_0->mList[i_0].d)>;
                            using ListMemberType_2 = ListMemberTypeGetter<ListType_2>::Type;
                            if (element_0.d.count != 0) {
                                auto * listHolder_2 = new ListHolder<ListMemberType_2>(element_0.d.count);
                                if (listHolder_2 == nullptr || listHolder_2->mList == nullptr) {
                                    return CHIP_ERROR_INVALID_ARGUMENT;
                                }
                                listFreer.add(listHolder_2);
                                for (size_t i_2 = 0; i_2 < element_0.d.count; ++i_2) {
                                    if (![element_0.d[i_2] isKindOfClass:[MTRUnitTestingClusterSimpleStruct class]]) {
                                        // Wrong kind of value.
                                        return CHIP_ERROR_INVALID_ARGUMENT;
                                    }
                                    auto element_2 = (MTRUnitTestingClusterSimpleStruct *) element_0.d[i_2];
                                    listHolder_2->mList[i_2].a = element_2.a.unsignedCharValue;
                                    listHolder_2->mList[i_2].b = element_2.b.boolValue;
                                    listHolder_2->mList[i_2].c
                                        = static_cast<std::remove_reference_t<decltype(listHolder_2->mList[i_2].c)>>(
                                            element_2.c.unsignedCharValue);
                                    listHolder_2->mList[i_2].d = [self asByteSpan:element_2.d];
                                    listHolder_2->mList[i_2].e = [self asCharSpan:element_2.e];
                                    listHolder_2->mList[i_2].f
                                        = static_cast<std::remove_reference_t<decltype(listHolder_2->mList[i_2].f)>>(
                                            element_2.f.unsignedCharValue);
                                    listHolder_2->mList[i_2].g = element_2.g.floatValue;
                                    listHolder_2->mList[i_2].h = element_2.h.doubleValue;
                                }
                                listHolder_0->mList[i_0].d = ListType_2(listHolder_2->mList, element_0.d.count);
                            } else {
                                listHolder_0->mList[i_0].d = ListType_2();
                            }
                        }
                        {
                            using ListType_2 = std::remove_reference_t<decltype(listHolder_0->mList[i_0].e)>;
                            using ListMemberType_2 = ListMemberTypeGetter<ListType_2>::Type;
                            if (element_0.e.count != 0) {
                                auto * listHolder_2 = new ListHolder<ListMemberType_2>(element_0.e.count);
                                if (listHolder_2 == nullptr || listHolder_2->mList == nullptr) {
                                    return CHIP_ERROR_INVALID_ARGUMENT;
                                }
                                listFreer.add(listHolder_2);
                                for (size_t i_2 = 0; i_2 < element_0.e.count; ++i_2) {
                                    if (![element_0.e[i_2] isKindOfClass:[NSNumber class]]) {
                                        // Wrong kind of value.
                                        return CHIP_ERROR_INVALID_ARGUMENT;
                                    }
                                    auto element_2 = (NSNumber *) element_0.e[i_2];
                                    listHolder_2->mList[i_2] = element_2.unsignedIntValue;
                                }
                                listHolder_0->mList[i_0].e = ListType_2(listHolder_2->mList, element_0.e.count);
                            } else {
                                listHolder_0->mList[i_0].e = ListType_2();
                            }
                        }
                        {
                            using ListType_2 = std::remove_reference_t<decltype(listHolder_0->mList[i_0].f)>;
                            using ListMemberType_2 = ListMemberTypeGetter<ListType_2>::Type;
                            if (element_0.f.count != 0) {
                                auto * listHolder_2 = new ListHolder<ListMemberType_2>(element_0.f.count);
                                if (listHolder_2 == nullptr || listHolder_2->mList == nullptr) {
                                    return CHIP_ERROR_INVALID_ARGUMENT;
                                }
                                listFreer.add(listHolder_2);
                                for (size_t i_2 = 0; i_2 < element_0.f.count; ++i_2) {
                                    if (![element_0.f[i_2] isKindOfClass:[NSData class]]) {
                                        // Wrong kind of value.
                                        return CHIP_ERROR_INVALID_ARGUMENT;
                                    }
                                    auto element_2 = (NSData *) element_0.f[i_2];
                                    listHolder_2->mList[i_2] = [self asByteSpan:element_2];
                                }
                                listHolder_0->mList[i_0].f = ListType_2(listHolder_2->mList, element_0.f.count);
                            } else {
                                listHolder_0->mList[i_0].f = ListType_2();
                            }
                        }
                        {
                            using ListType_2 = std::remove_reference_t<decltype(listHolder_0->mList[i_0].g)>;
                            using ListMemberType_2 = ListMemberTypeGetter<ListType_2>::Type;
                            if (element_0.g.count != 0) {
                                auto * listHolder_2 = new ListHolder<ListMemberType_2>(element_0.g.count);
                                if (listHolder_2 == nullptr || listHolder_2->mList == nullptr) {
                                    return CHIP_ERROR_INVALID_ARGUMENT;
                                }
                                listFreer.add(listHolder_2);
                                for (size_t i_2 = 0; i_2 < element_0.g.count; ++i_2) {
                                    if (![element_0.g[i_2] isKindOfClass:[NSNumber class]]) {
                                        // Wrong kind of value.
                                        return CHIP_ERROR_INVALID_ARGUMENT;
                                    }
                                    auto element_2 = (NSNumber *) element_0.g[i_2];
                                    listHolder_2->mList[i_2] = element_2.unsignedCharValue;
                                }
                                listHolder_0->mList[i_0].g = ListType_2(listHolder_2->mList, element_0.g.count);
                            } else {
                                listHolder_0->mList[i_0].g = ListType_2();
                            }
                        }
                    }
                    request.arg1 = ListType_0(listHolder_0->mList, params.arg1.count);
                } else {
                    request.arg1 = ListType_0();
                }
            }
            {
                using ListType_0 = std::remove_reference_t<decltype(request.arg2)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (params.arg2.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(params.arg2.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < params.arg2.count; ++i_0) {
                        if (![params.arg2[i_0] isKindOfClass:[MTRUnitTestingClusterSimpleStruct class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (MTRUnitTestingClusterSimpleStruct *) params.arg2[i_0];
                        listHolder_0->mList[i_0].a = element_0.a.unsignedCharValue;
                        listHolder_0->mList[i_0].b = element_0.b.boolValue;
                        listHolder_0->mList[i_0].c = static_cast<std::remove_reference_t<decltype(listHolder_0->mList[i_0].c)>>(
                            element_0.c.unsignedCharValue);
                        listHolder_0->mList[i_0].d = [self asByteSpan:element_0.d];
                        listHolder_0->mList[i_0].e = [self asCharSpan:element_0.e];
                        listHolder_0->mList[i_0].f = static_cast<std::remove_reference_t<decltype(listHolder_0->mList[i_0].f)>>(
                            element_0.f.unsignedCharValue);
                        listHolder_0->mList[i_0].g = element_0.g.floatValue;
                        listHolder_0->mList[i_0].h = element_0.h.doubleValue;
                    }
                    request.arg2 = ListType_0(listHolder_0->mList, params.arg2.count);
                } else {
                    request.arg2 = ListType_0();
                }
            }
            {
                using ListType_0 = std::remove_reference_t<decltype(request.arg3)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (params.arg3.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(params.arg3.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < params.arg3.count; ++i_0) {
                        if (![params.arg3[i_0] isKindOfClass:[NSNumber class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (NSNumber *) params.arg3[i_0];
                        listHolder_0->mList[i_0]
                            = static_cast<std::remove_reference_t<decltype(listHolder_0->mList[i_0])>>(element_0.unsignedCharValue);
                    }
                    request.arg3 = ListType_0(listHolder_0->mList, params.arg3.count);
                } else {
                    request.arg3 = ListType_0();
                }
            }
            {
                using ListType_0 = std::remove_reference_t<decltype(request.arg4)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (params.arg4.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(params.arg4.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < params.arg4.count; ++i_0) {
                        if (![params.arg4[i_0] isKindOfClass:[NSNumber class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (NSNumber *) params.arg4[i_0];
                        listHolder_0->mList[i_0] = element_0.boolValue;
                    }
                    request.arg4 = ListType_0(listHolder_0->mList, params.arg4.count);
                } else {
                    request.arg4 = ListType_0();
                }
            }
            request.arg5 = static_cast<std::remove_reference_t<decltype(request.arg5)>>(params.arg5.unsignedCharValue);
            request.arg6 = params.arg6.boolValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)testStructArgumentRequestWithParams:(MTRUnitTestingClusterTestStructArgumentRequestParams *)params
                                 completion:(void (^)(MTRUnitTestingClusterBooleanResponseParams * _Nullable data,
                                                NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRUnitTestingClusterBooleanResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, UnitTestingClusterBooleanResponseCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRUnitTestingClusterBooleanResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            UnitTesting::Commands::TestStructArgumentRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.arg1.a = params.arg1.a.unsignedCharValue;
            request.arg1.b = params.arg1.b.boolValue;
            request.arg1.c = static_cast<std::remove_reference_t<decltype(request.arg1.c)>>(params.arg1.c.unsignedCharValue);
            request.arg1.d = [self asByteSpan:params.arg1.d];
            request.arg1.e = [self asCharSpan:params.arg1.e];
            request.arg1.f = static_cast<std::remove_reference_t<decltype(request.arg1.f)>>(params.arg1.f.unsignedCharValue);
            request.arg1.g = params.arg1.g.floatValue;
            request.arg1.h = params.arg1.h.doubleValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)testNestedStructArgumentRequestWithParams:(MTRUnitTestingClusterTestNestedStructArgumentRequestParams *)params
                                       completion:(void (^)(MTRUnitTestingClusterBooleanResponseParams * _Nullable data,
                                                      NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRUnitTestingClusterBooleanResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, UnitTestingClusterBooleanResponseCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRUnitTestingClusterBooleanResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            UnitTesting::Commands::TestNestedStructArgumentRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.arg1.a = params.arg1.a.unsignedCharValue;
            request.arg1.b = params.arg1.b.boolValue;
            request.arg1.c.a = params.arg1.c.a.unsignedCharValue;
            request.arg1.c.b = params.arg1.c.b.boolValue;
            request.arg1.c.c = static_cast<std::remove_reference_t<decltype(request.arg1.c.c)>>(params.arg1.c.c.unsignedCharValue);
            request.arg1.c.d = [self asByteSpan:params.arg1.c.d];
            request.arg1.c.e = [self asCharSpan:params.arg1.c.e];
            request.arg1.c.f = static_cast<std::remove_reference_t<decltype(request.arg1.c.f)>>(params.arg1.c.f.unsignedCharValue);
            request.arg1.c.g = params.arg1.c.g.floatValue;
            request.arg1.c.h = params.arg1.c.h.doubleValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)testListStructArgumentRequestWithParams:(MTRUnitTestingClusterTestListStructArgumentRequestParams *)params
                                     completion:(void (^)(MTRUnitTestingClusterBooleanResponseParams * _Nullable data,
                                                    NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRUnitTestingClusterBooleanResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, UnitTestingClusterBooleanResponseCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRUnitTestingClusterBooleanResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            UnitTesting::Commands::TestListStructArgumentRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            {
                using ListType_0 = std::remove_reference_t<decltype(request.arg1)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (params.arg1.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(params.arg1.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < params.arg1.count; ++i_0) {
                        if (![params.arg1[i_0] isKindOfClass:[MTRUnitTestingClusterSimpleStruct class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (MTRUnitTestingClusterSimpleStruct *) params.arg1[i_0];
                        listHolder_0->mList[i_0].a = element_0.a.unsignedCharValue;
                        listHolder_0->mList[i_0].b = element_0.b.boolValue;
                        listHolder_0->mList[i_0].c = static_cast<std::remove_reference_t<decltype(listHolder_0->mList[i_0].c)>>(
                            element_0.c.unsignedCharValue);
                        listHolder_0->mList[i_0].d = [self asByteSpan:element_0.d];
                        listHolder_0->mList[i_0].e = [self asCharSpan:element_0.e];
                        listHolder_0->mList[i_0].f = static_cast<std::remove_reference_t<decltype(listHolder_0->mList[i_0].f)>>(
                            element_0.f.unsignedCharValue);
                        listHolder_0->mList[i_0].g = element_0.g.floatValue;
                        listHolder_0->mList[i_0].h = element_0.h.doubleValue;
                    }
                    request.arg1 = ListType_0(listHolder_0->mList, params.arg1.count);
                } else {
                    request.arg1 = ListType_0();
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)testListInt8UArgumentRequestWithParams:(MTRUnitTestingClusterTestListInt8UArgumentRequestParams *)params
                                    completion:(void (^)(MTRUnitTestingClusterBooleanResponseParams * _Nullable data,
                                                   NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRUnitTestingClusterBooleanResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, UnitTestingClusterBooleanResponseCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRUnitTestingClusterBooleanResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            UnitTesting::Commands::TestListInt8UArgumentRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            {
                using ListType_0 = std::remove_reference_t<decltype(request.arg1)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (params.arg1.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(params.arg1.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < params.arg1.count; ++i_0) {
                        if (![params.arg1[i_0] isKindOfClass:[NSNumber class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (NSNumber *) params.arg1[i_0];
                        listHolder_0->mList[i_0] = element_0.unsignedCharValue;
                    }
                    request.arg1 = ListType_0(listHolder_0->mList, params.arg1.count);
                } else {
                    request.arg1 = ListType_0();
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)testNestedStructListArgumentRequestWithParams:(MTRUnitTestingClusterTestNestedStructListArgumentRequestParams *)params
                                           completion:(void (^)(MTRUnitTestingClusterBooleanResponseParams * _Nullable data,
                                                          NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRUnitTestingClusterBooleanResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, UnitTestingClusterBooleanResponseCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRUnitTestingClusterBooleanResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            UnitTesting::Commands::TestNestedStructListArgumentRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.arg1.a = params.arg1.a.unsignedCharValue;
            request.arg1.b = params.arg1.b.boolValue;
            request.arg1.c.a = params.arg1.c.a.unsignedCharValue;
            request.arg1.c.b = params.arg1.c.b.boolValue;
            request.arg1.c.c = static_cast<std::remove_reference_t<decltype(request.arg1.c.c)>>(params.arg1.c.c.unsignedCharValue);
            request.arg1.c.d = [self asByteSpan:params.arg1.c.d];
            request.arg1.c.e = [self asCharSpan:params.arg1.c.e];
            request.arg1.c.f = static_cast<std::remove_reference_t<decltype(request.arg1.c.f)>>(params.arg1.c.f.unsignedCharValue);
            request.arg1.c.g = params.arg1.c.g.floatValue;
            request.arg1.c.h = params.arg1.c.h.doubleValue;
            {
                using ListType_1 = std::remove_reference_t<decltype(request.arg1.d)>;
                using ListMemberType_1 = ListMemberTypeGetter<ListType_1>::Type;
                if (params.arg1.d.count != 0) {
                    auto * listHolder_1 = new ListHolder<ListMemberType_1>(params.arg1.d.count);
                    if (listHolder_1 == nullptr || listHolder_1->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_1);
                    for (size_t i_1 = 0; i_1 < params.arg1.d.count; ++i_1) {
                        if (![params.arg1.d[i_1] isKindOfClass:[MTRUnitTestingClusterSimpleStruct class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_1 = (MTRUnitTestingClusterSimpleStruct *) params.arg1.d[i_1];
                        listHolder_1->mList[i_1].a = element_1.a.unsignedCharValue;
                        listHolder_1->mList[i_1].b = element_1.b.boolValue;
                        listHolder_1->mList[i_1].c = static_cast<std::remove_reference_t<decltype(listHolder_1->mList[i_1].c)>>(
                            element_1.c.unsignedCharValue);
                        listHolder_1->mList[i_1].d = [self asByteSpan:element_1.d];
                        listHolder_1->mList[i_1].e = [self asCharSpan:element_1.e];
                        listHolder_1->mList[i_1].f = static_cast<std::remove_reference_t<decltype(listHolder_1->mList[i_1].f)>>(
                            element_1.f.unsignedCharValue);
                        listHolder_1->mList[i_1].g = element_1.g.floatValue;
                        listHolder_1->mList[i_1].h = element_1.h.doubleValue;
                    }
                    request.arg1.d = ListType_1(listHolder_1->mList, params.arg1.d.count);
                } else {
                    request.arg1.d = ListType_1();
                }
            }
            {
                using ListType_1 = std::remove_reference_t<decltype(request.arg1.e)>;
                using ListMemberType_1 = ListMemberTypeGetter<ListType_1>::Type;
                if (params.arg1.e.count != 0) {
                    auto * listHolder_1 = new ListHolder<ListMemberType_1>(params.arg1.e.count);
                    if (listHolder_1 == nullptr || listHolder_1->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_1);
                    for (size_t i_1 = 0; i_1 < params.arg1.e.count; ++i_1) {
                        if (![params.arg1.e[i_1] isKindOfClass:[NSNumber class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_1 = (NSNumber *) params.arg1.e[i_1];
                        listHolder_1->mList[i_1] = element_1.unsignedIntValue;
                    }
                    request.arg1.e = ListType_1(listHolder_1->mList, params.arg1.e.count);
                } else {
                    request.arg1.e = ListType_1();
                }
            }
            {
                using ListType_1 = std::remove_reference_t<decltype(request.arg1.f)>;
                using ListMemberType_1 = ListMemberTypeGetter<ListType_1>::Type;
                if (params.arg1.f.count != 0) {
                    auto * listHolder_1 = new ListHolder<ListMemberType_1>(params.arg1.f.count);
                    if (listHolder_1 == nullptr || listHolder_1->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_1);
                    for (size_t i_1 = 0; i_1 < params.arg1.f.count; ++i_1) {
                        if (![params.arg1.f[i_1] isKindOfClass:[NSData class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_1 = (NSData *) params.arg1.f[i_1];
                        listHolder_1->mList[i_1] = [self asByteSpan:element_1];
                    }
                    request.arg1.f = ListType_1(listHolder_1->mList, params.arg1.f.count);
                } else {
                    request.arg1.f = ListType_1();
                }
            }
            {
                using ListType_1 = std::remove_reference_t<decltype(request.arg1.g)>;
                using ListMemberType_1 = ListMemberTypeGetter<ListType_1>::Type;
                if (params.arg1.g.count != 0) {
                    auto * listHolder_1 = new ListHolder<ListMemberType_1>(params.arg1.g.count);
                    if (listHolder_1 == nullptr || listHolder_1->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_1);
                    for (size_t i_1 = 0; i_1 < params.arg1.g.count; ++i_1) {
                        if (![params.arg1.g[i_1] isKindOfClass:[NSNumber class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_1 = (NSNumber *) params.arg1.g[i_1];
                        listHolder_1->mList[i_1] = element_1.unsignedCharValue;
                    }
                    request.arg1.g = ListType_1(listHolder_1->mList, params.arg1.g.count);
                } else {
                    request.arg1.g = ListType_1();
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)testListNestedStructListArgumentRequestWithParams:
            (MTRUnitTestingClusterTestListNestedStructListArgumentRequestParams *)params
                                               completion:(void (^)(MTRUnitTestingClusterBooleanResponseParams * _Nullable data,
                                                              NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRUnitTestingClusterBooleanResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, UnitTestingClusterBooleanResponseCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRUnitTestingClusterBooleanResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            UnitTesting::Commands::TestListNestedStructListArgumentRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            {
                using ListType_0 = std::remove_reference_t<decltype(request.arg1)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (params.arg1.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(params.arg1.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < params.arg1.count; ++i_0) {
                        if (![params.arg1[i_0] isKindOfClass:[MTRUnitTestingClusterNestedStructList class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (MTRUnitTestingClusterNestedStructList *) params.arg1[i_0];
                        listHolder_0->mList[i_0].a = element_0.a.unsignedCharValue;
                        listHolder_0->mList[i_0].b = element_0.b.boolValue;
                        listHolder_0->mList[i_0].c.a = element_0.c.a.unsignedCharValue;
                        listHolder_0->mList[i_0].c.b = element_0.c.b.boolValue;
                        listHolder_0->mList[i_0].c.c = static_cast<std::remove_reference_t<decltype(listHolder_0->mList[i_0].c.c)>>(
                            element_0.c.c.unsignedCharValue);
                        listHolder_0->mList[i_0].c.d = [self asByteSpan:element_0.c.d];
                        listHolder_0->mList[i_0].c.e = [self asCharSpan:element_0.c.e];
                        listHolder_0->mList[i_0].c.f = static_cast<std::remove_reference_t<decltype(listHolder_0->mList[i_0].c.f)>>(
                            element_0.c.f.unsignedCharValue);
                        listHolder_0->mList[i_0].c.g = element_0.c.g.floatValue;
                        listHolder_0->mList[i_0].c.h = element_0.c.h.doubleValue;
                        {
                            using ListType_2 = std::remove_reference_t<decltype(listHolder_0->mList[i_0].d)>;
                            using ListMemberType_2 = ListMemberTypeGetter<ListType_2>::Type;
                            if (element_0.d.count != 0) {
                                auto * listHolder_2 = new ListHolder<ListMemberType_2>(element_0.d.count);
                                if (listHolder_2 == nullptr || listHolder_2->mList == nullptr) {
                                    return CHIP_ERROR_INVALID_ARGUMENT;
                                }
                                listFreer.add(listHolder_2);
                                for (size_t i_2 = 0; i_2 < element_0.d.count; ++i_2) {
                                    if (![element_0.d[i_2] isKindOfClass:[MTRUnitTestingClusterSimpleStruct class]]) {
                                        // Wrong kind of value.
                                        return CHIP_ERROR_INVALID_ARGUMENT;
                                    }
                                    auto element_2 = (MTRUnitTestingClusterSimpleStruct *) element_0.d[i_2];
                                    listHolder_2->mList[i_2].a = element_2.a.unsignedCharValue;
                                    listHolder_2->mList[i_2].b = element_2.b.boolValue;
                                    listHolder_2->mList[i_2].c
                                        = static_cast<std::remove_reference_t<decltype(listHolder_2->mList[i_2].c)>>(
                                            element_2.c.unsignedCharValue);
                                    listHolder_2->mList[i_2].d = [self asByteSpan:element_2.d];
                                    listHolder_2->mList[i_2].e = [self asCharSpan:element_2.e];
                                    listHolder_2->mList[i_2].f
                                        = static_cast<std::remove_reference_t<decltype(listHolder_2->mList[i_2].f)>>(
                                            element_2.f.unsignedCharValue);
                                    listHolder_2->mList[i_2].g = element_2.g.floatValue;
                                    listHolder_2->mList[i_2].h = element_2.h.doubleValue;
                                }
                                listHolder_0->mList[i_0].d = ListType_2(listHolder_2->mList, element_0.d.count);
                            } else {
                                listHolder_0->mList[i_0].d = ListType_2();
                            }
                        }
                        {
                            using ListType_2 = std::remove_reference_t<decltype(listHolder_0->mList[i_0].e)>;
                            using ListMemberType_2 = ListMemberTypeGetter<ListType_2>::Type;
                            if (element_0.e.count != 0) {
                                auto * listHolder_2 = new ListHolder<ListMemberType_2>(element_0.e.count);
                                if (listHolder_2 == nullptr || listHolder_2->mList == nullptr) {
                                    return CHIP_ERROR_INVALID_ARGUMENT;
                                }
                                listFreer.add(listHolder_2);
                                for (size_t i_2 = 0; i_2 < element_0.e.count; ++i_2) {
                                    if (![element_0.e[i_2] isKindOfClass:[NSNumber class]]) {
                                        // Wrong kind of value.
                                        return CHIP_ERROR_INVALID_ARGUMENT;
                                    }
                                    auto element_2 = (NSNumber *) element_0.e[i_2];
                                    listHolder_2->mList[i_2] = element_2.unsignedIntValue;
                                }
                                listHolder_0->mList[i_0].e = ListType_2(listHolder_2->mList, element_0.e.count);
                            } else {
                                listHolder_0->mList[i_0].e = ListType_2();
                            }
                        }
                        {
                            using ListType_2 = std::remove_reference_t<decltype(listHolder_0->mList[i_0].f)>;
                            using ListMemberType_2 = ListMemberTypeGetter<ListType_2>::Type;
                            if (element_0.f.count != 0) {
                                auto * listHolder_2 = new ListHolder<ListMemberType_2>(element_0.f.count);
                                if (listHolder_2 == nullptr || listHolder_2->mList == nullptr) {
                                    return CHIP_ERROR_INVALID_ARGUMENT;
                                }
                                listFreer.add(listHolder_2);
                                for (size_t i_2 = 0; i_2 < element_0.f.count; ++i_2) {
                                    if (![element_0.f[i_2] isKindOfClass:[NSData class]]) {
                                        // Wrong kind of value.
                                        return CHIP_ERROR_INVALID_ARGUMENT;
                                    }
                                    auto element_2 = (NSData *) element_0.f[i_2];
                                    listHolder_2->mList[i_2] = [self asByteSpan:element_2];
                                }
                                listHolder_0->mList[i_0].f = ListType_2(listHolder_2->mList, element_0.f.count);
                            } else {
                                listHolder_0->mList[i_0].f = ListType_2();
                            }
                        }
                        {
                            using ListType_2 = std::remove_reference_t<decltype(listHolder_0->mList[i_0].g)>;
                            using ListMemberType_2 = ListMemberTypeGetter<ListType_2>::Type;
                            if (element_0.g.count != 0) {
                                auto * listHolder_2 = new ListHolder<ListMemberType_2>(element_0.g.count);
                                if (listHolder_2 == nullptr || listHolder_2->mList == nullptr) {
                                    return CHIP_ERROR_INVALID_ARGUMENT;
                                }
                                listFreer.add(listHolder_2);
                                for (size_t i_2 = 0; i_2 < element_0.g.count; ++i_2) {
                                    if (![element_0.g[i_2] isKindOfClass:[NSNumber class]]) {
                                        // Wrong kind of value.
                                        return CHIP_ERROR_INVALID_ARGUMENT;
                                    }
                                    auto element_2 = (NSNumber *) element_0.g[i_2];
                                    listHolder_2->mList[i_2] = element_2.unsignedCharValue;
                                }
                                listHolder_0->mList[i_0].g = ListType_2(listHolder_2->mList, element_0.g.count);
                            } else {
                                listHolder_0->mList[i_0].g = ListType_2();
                            }
                        }
                    }
                    request.arg1 = ListType_0(listHolder_0->mList, params.arg1.count);
                } else {
                    request.arg1 = ListType_0();
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)testListInt8UReverseRequestWithParams:(MTRUnitTestingClusterTestListInt8UReverseRequestParams *)params
                                   completion:(void (^)(MTRUnitTestingClusterTestListInt8UReverseResponseParams * _Nullable data,
                                                  NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRUnitTestingClusterTestListInt8UReverseResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            UnitTestingClusterTestListInt8UReverseResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRUnitTestingClusterTestListInt8UReverseResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            UnitTesting::Commands::TestListInt8UReverseRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            {
                using ListType_0 = std::remove_reference_t<decltype(request.arg1)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (params.arg1.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(params.arg1.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < params.arg1.count; ++i_0) {
                        if (![params.arg1[i_0] isKindOfClass:[NSNumber class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (NSNumber *) params.arg1[i_0];
                        listHolder_0->mList[i_0] = element_0.unsignedCharValue;
                    }
                    request.arg1 = ListType_0(listHolder_0->mList, params.arg1.count);
                } else {
                    request.arg1 = ListType_0();
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)testEnumsRequestWithParams:(MTRUnitTestingClusterTestEnumsRequestParams *)params
                        completion:(void (^)(MTRUnitTestingClusterTestEnumsResponseParams * _Nullable data,
                                       NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRUnitTestingClusterTestEnumsResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            UnitTestingClusterTestEnumsResponseCallbackType successCb, MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRUnitTestingClusterTestEnumsResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            UnitTesting::Commands::TestEnumsRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.arg1 = static_cast<std::remove_reference_t<decltype(request.arg1)>>(params.arg1.unsignedShortValue);
            request.arg2 = static_cast<std::remove_reference_t<decltype(request.arg2)>>(params.arg2.unsignedCharValue);

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)testNullableOptionalRequestWithParams:(MTRUnitTestingClusterTestNullableOptionalRequestParams * _Nullable)params
                                   completion:(void (^)(MTRUnitTestingClusterTestNullableOptionalResponseParams * _Nullable data,
                                                  NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRUnitTestingClusterTestNullableOptionalResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            UnitTestingClusterTestNullableOptionalResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRUnitTestingClusterTestNullableOptionalResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            UnitTesting::Commands::TestNullableOptionalRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            if (params != nil) {
                if (params.arg1 != nil) {
                    auto & definedValue_0 = request.arg1.Emplace();
                    if (params.arg1 == nil) {
                        definedValue_0.SetNull();
                    } else {
                        auto & nonNullValue_1 = definedValue_0.SetNonNull();
                        nonNullValue_1 = params.arg1.unsignedCharValue;
                    }
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)testComplexNullableOptionalRequestWithParams:(MTRUnitTestingClusterTestComplexNullableOptionalRequestParams *)params
                                          completion:
                                              (void (^)(
                                                  MTRUnitTestingClusterTestComplexNullableOptionalResponseParams * _Nullable data,
                                                  NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRUnitTestingClusterTestComplexNullableOptionalResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            UnitTestingClusterTestComplexNullableOptionalResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRUnitTestingClusterTestComplexNullableOptionalResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            UnitTesting::Commands::TestComplexNullableOptionalRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            if (params.nullableInt == nil) {
                request.nullableInt.SetNull();
            } else {
                auto & nonNullValue_0 = request.nullableInt.SetNonNull();
                nonNullValue_0 = params.nullableInt.unsignedShortValue;
            }
            if (params.optionalInt != nil) {
                auto & definedValue_0 = request.optionalInt.Emplace();
                definedValue_0 = params.optionalInt.unsignedShortValue;
            }
            if (params.nullableOptionalInt != nil) {
                auto & definedValue_0 = request.nullableOptionalInt.Emplace();
                if (params.nullableOptionalInt == nil) {
                    definedValue_0.SetNull();
                } else {
                    auto & nonNullValue_1 = definedValue_0.SetNonNull();
                    nonNullValue_1 = params.nullableOptionalInt.unsignedShortValue;
                }
            }
            if (params.nullableString == nil) {
                request.nullableString.SetNull();
            } else {
                auto & nonNullValue_0 = request.nullableString.SetNonNull();
                nonNullValue_0 = [self asCharSpan:params.nullableString];
            }
            if (params.optionalString != nil) {
                auto & definedValue_0 = request.optionalString.Emplace();
                definedValue_0 = [self asCharSpan:params.optionalString];
            }
            if (params.nullableOptionalString != nil) {
                auto & definedValue_0 = request.nullableOptionalString.Emplace();
                if (params.nullableOptionalString == nil) {
                    definedValue_0.SetNull();
                } else {
                    auto & nonNullValue_1 = definedValue_0.SetNonNull();
                    nonNullValue_1 = [self asCharSpan:params.nullableOptionalString];
                }
            }
            if (params.nullableStruct == nil) {
                request.nullableStruct.SetNull();
            } else {
                auto & nonNullValue_0 = request.nullableStruct.SetNonNull();
                nonNullValue_0.a = params.nullableStruct.a.unsignedCharValue;
                nonNullValue_0.b = params.nullableStruct.b.boolValue;
                nonNullValue_0.c
                    = static_cast<std::remove_reference_t<decltype(nonNullValue_0.c)>>(params.nullableStruct.c.unsignedCharValue);
                nonNullValue_0.d = [self asByteSpan:params.nullableStruct.d];
                nonNullValue_0.e = [self asCharSpan:params.nullableStruct.e];
                nonNullValue_0.f
                    = static_cast<std::remove_reference_t<decltype(nonNullValue_0.f)>>(params.nullableStruct.f.unsignedCharValue);
                nonNullValue_0.g = params.nullableStruct.g.floatValue;
                nonNullValue_0.h = params.nullableStruct.h.doubleValue;
            }
            if (params.optionalStruct != nil) {
                auto & definedValue_0 = request.optionalStruct.Emplace();
                definedValue_0.a = params.optionalStruct.a.unsignedCharValue;
                definedValue_0.b = params.optionalStruct.b.boolValue;
                definedValue_0.c
                    = static_cast<std::remove_reference_t<decltype(definedValue_0.c)>>(params.optionalStruct.c.unsignedCharValue);
                definedValue_0.d = [self asByteSpan:params.optionalStruct.d];
                definedValue_0.e = [self asCharSpan:params.optionalStruct.e];
                definedValue_0.f
                    = static_cast<std::remove_reference_t<decltype(definedValue_0.f)>>(params.optionalStruct.f.unsignedCharValue);
                definedValue_0.g = params.optionalStruct.g.floatValue;
                definedValue_0.h = params.optionalStruct.h.doubleValue;
            }
            if (params.nullableOptionalStruct != nil) {
                auto & definedValue_0 = request.nullableOptionalStruct.Emplace();
                if (params.nullableOptionalStruct == nil) {
                    definedValue_0.SetNull();
                } else {
                    auto & nonNullValue_1 = definedValue_0.SetNonNull();
                    nonNullValue_1.a = params.nullableOptionalStruct.a.unsignedCharValue;
                    nonNullValue_1.b = params.nullableOptionalStruct.b.boolValue;
                    nonNullValue_1.c = static_cast<std::remove_reference_t<decltype(nonNullValue_1.c)>>(
                        params.nullableOptionalStruct.c.unsignedCharValue);
                    nonNullValue_1.d = [self asByteSpan:params.nullableOptionalStruct.d];
                    nonNullValue_1.e = [self asCharSpan:params.nullableOptionalStruct.e];
                    nonNullValue_1.f = static_cast<std::remove_reference_t<decltype(nonNullValue_1.f)>>(
                        params.nullableOptionalStruct.f.unsignedCharValue);
                    nonNullValue_1.g = params.nullableOptionalStruct.g.floatValue;
                    nonNullValue_1.h = params.nullableOptionalStruct.h.doubleValue;
                }
            }
            if (params.nullableList == nil) {
                request.nullableList.SetNull();
            } else {
                auto & nonNullValue_0 = request.nullableList.SetNonNull();
                {
                    using ListType_1 = std::remove_reference_t<decltype(nonNullValue_0)>;
                    using ListMemberType_1 = ListMemberTypeGetter<ListType_1>::Type;
                    if (params.nullableList.count != 0) {
                        auto * listHolder_1 = new ListHolder<ListMemberType_1>(params.nullableList.count);
                        if (listHolder_1 == nullptr || listHolder_1->mList == nullptr) {
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        listFreer.add(listHolder_1);
                        for (size_t i_1 = 0; i_1 < params.nullableList.count; ++i_1) {
                            if (![params.nullableList[i_1] isKindOfClass:[NSNumber class]]) {
                                // Wrong kind of value.
                                return CHIP_ERROR_INVALID_ARGUMENT;
                            }
                            auto element_1 = (NSNumber *) params.nullableList[i_1];
                            listHolder_1->mList[i_1] = static_cast<std::remove_reference_t<decltype(listHolder_1->mList[i_1])>>(
                                element_1.unsignedCharValue);
                        }
                        nonNullValue_0 = ListType_1(listHolder_1->mList, params.nullableList.count);
                    } else {
                        nonNullValue_0 = ListType_1();
                    }
                }
            }
            if (params.optionalList != nil) {
                auto & definedValue_0 = request.optionalList.Emplace();
                {
                    using ListType_1 = std::remove_reference_t<decltype(definedValue_0)>;
                    using ListMemberType_1 = ListMemberTypeGetter<ListType_1>::Type;
                    if (params.optionalList.count != 0) {
                        auto * listHolder_1 = new ListHolder<ListMemberType_1>(params.optionalList.count);
                        if (listHolder_1 == nullptr || listHolder_1->mList == nullptr) {
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        listFreer.add(listHolder_1);
                        for (size_t i_1 = 0; i_1 < params.optionalList.count; ++i_1) {
                            if (![params.optionalList[i_1] isKindOfClass:[NSNumber class]]) {
                                // Wrong kind of value.
                                return CHIP_ERROR_INVALID_ARGUMENT;
                            }
                            auto element_1 = (NSNumber *) params.optionalList[i_1];
                            listHolder_1->mList[i_1] = static_cast<std::remove_reference_t<decltype(listHolder_1->mList[i_1])>>(
                                element_1.unsignedCharValue);
                        }
                        definedValue_0 = ListType_1(listHolder_1->mList, params.optionalList.count);
                    } else {
                        definedValue_0 = ListType_1();
                    }
                }
            }
            if (params.nullableOptionalList != nil) {
                auto & definedValue_0 = request.nullableOptionalList.Emplace();
                if (params.nullableOptionalList == nil) {
                    definedValue_0.SetNull();
                } else {
                    auto & nonNullValue_1 = definedValue_0.SetNonNull();
                    {
                        using ListType_2 = std::remove_reference_t<decltype(nonNullValue_1)>;
                        using ListMemberType_2 = ListMemberTypeGetter<ListType_2>::Type;
                        if (params.nullableOptionalList.count != 0) {
                            auto * listHolder_2 = new ListHolder<ListMemberType_2>(params.nullableOptionalList.count);
                            if (listHolder_2 == nullptr || listHolder_2->mList == nullptr) {
                                return CHIP_ERROR_INVALID_ARGUMENT;
                            }
                            listFreer.add(listHolder_2);
                            for (size_t i_2 = 0; i_2 < params.nullableOptionalList.count; ++i_2) {
                                if (![params.nullableOptionalList[i_2] isKindOfClass:[NSNumber class]]) {
                                    // Wrong kind of value.
                                    return CHIP_ERROR_INVALID_ARGUMENT;
                                }
                                auto element_2 = (NSNumber *) params.nullableOptionalList[i_2];
                                listHolder_2->mList[i_2] = static_cast<std::remove_reference_t<decltype(listHolder_2->mList[i_2])>>(
                                    element_2.unsignedCharValue);
                            }
                            nonNullValue_1 = ListType_2(listHolder_2->mList, params.nullableOptionalList.count);
                        } else {
                            nonNullValue_1 = ListType_2();
                        }
                    }
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)simpleStructEchoRequestWithParams:(MTRUnitTestingClusterSimpleStructEchoRequestParams *)params
                               completion:(void (^)(MTRUnitTestingClusterSimpleStructResponseParams * _Nullable data,
                                              NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRUnitTestingClusterSimpleStructResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            UnitTestingClusterSimpleStructResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRUnitTestingClusterSimpleStructResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            UnitTesting::Commands::SimpleStructEchoRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.arg1.a = params.arg1.a.unsignedCharValue;
            request.arg1.b = params.arg1.b.boolValue;
            request.arg1.c = static_cast<std::remove_reference_t<decltype(request.arg1.c)>>(params.arg1.c.unsignedCharValue);
            request.arg1.d = [self asByteSpan:params.arg1.d];
            request.arg1.e = [self asCharSpan:params.arg1.e];
            request.arg1.f = static_cast<std::remove_reference_t<decltype(request.arg1.f)>>(params.arg1.f.unsignedCharValue);
            request.arg1.g = params.arg1.g.floatValue;
            request.arg1.h = params.arg1.h.doubleValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)timedInvokeRequestWithCompletion:(MTRStatusCompletion)completion
{
    [self timedInvokeRequestWithParams:nil completion:completion];
}
- (void)timedInvokeRequestWithParams:(MTRUnitTestingClusterTimedInvokeRequestParams * _Nullable)params
                          completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            UnitTesting::Commands::TimedInvokeRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            if (!timedInvokeTimeoutMs.HasValue()) {
                timedInvokeTimeoutMs.SetValue(10000);
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)testSimpleOptionalArgumentRequestWithParams:(MTRUnitTestingClusterTestSimpleOptionalArgumentRequestParams * _Nullable)params
                                         completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRCommandSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable value, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, CommandSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRCommandSuccessCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            UnitTesting::Commands::TestSimpleOptionalArgumentRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            if (params != nil) {
                if (params.arg1 != nil) {
                    auto & definedValue_0 = request.arg1.Emplace();
                    definedValue_0 = params.arg1.boolValue;
                }
            }

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)testEmitTestEventRequestWithParams:(MTRUnitTestingClusterTestEmitTestEventRequestParams *)params
                                completion:(void (^)(MTRUnitTestingClusterTestEmitTestEventResponseParams * _Nullable data,
                                               NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRUnitTestingClusterTestEmitTestEventResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            UnitTestingClusterTestEmitTestEventResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRUnitTestingClusterTestEmitTestEventResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            UnitTesting::Commands::TestEmitTestEventRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.arg1 = params.arg1.unsignedCharValue;
            request.arg2 = static_cast<std::remove_reference_t<decltype(request.arg2)>>(params.arg2.unsignedCharValue);
            request.arg3 = params.arg3.boolValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)
    testEmitTestFabricScopedEventRequestWithParams:(MTRUnitTestingClusterTestEmitTestFabricScopedEventRequestParams *)params
                                        completion:
                                            (void (^)(
                                                MTRUnitTestingClusterTestEmitTestFabricScopedEventResponseParams * _Nullable data,
                                                NSError * _Nullable error))completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTRUnitTestingClusterTestEmitTestFabricScopedEventResponseCallbackBridge(self.callbackQueue, completion,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session,
            UnitTestingClusterTestEmitTestFabricScopedEventResponseCallbackType successCb, MTRErrorCallback failureCb,
            MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTRUnitTestingClusterTestEmitTestFabricScopedEventResponseCallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            UnitTesting::Commands::TestEmitTestFabricScopedEventRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    params.timedInvokeTimeoutMs = MTRClampedNumber(params.timedInvokeTimeoutMs, @(1), @(UINT16_MAX));
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
                if (params.serverSideProcessingTimeout != nil) {
                    // Clamp to a number of seconds that will not overflow 32-bit
                    // int when converted to ms.
                    auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                    invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
                }
            }
            request.arg1 = params.arg1.unsignedCharValue;

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint,
                timedInvokeTimeoutMs, invokeTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)readAttributeBooleanWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::Boolean::TypeInfo;
    return MTRReadAttribute<MTRBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeBooleanWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeBooleanWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeBooleanWithValue:(NSNumber * _Nonnull)value
                                params:(MTRWriteParams * _Nullable)params
                            completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::Boolean::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.boolValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeBooleanWithParams:(MTRSubscribeParams * _Nonnull)params
                    subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                              reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::Boolean::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeBooleanWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                       completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::Boolean::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBitmap8WithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::Bitmap8::TypeInfo;
    return MTRReadAttribute<MTRUnitTestingBitmap8AttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeBitmap8WithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeBitmap8WithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeBitmap8WithValue:(NSNumber * _Nonnull)value
                                params:(MTRWriteParams * _Nullable)params
                            completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::Bitmap8::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = static_cast<std::remove_reference_t<decltype(cppValue)>>(value.unsignedCharValue);

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeBitmap8WithParams:(MTRSubscribeParams * _Nonnull)params
                    subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                              reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::Bitmap8::TypeInfo;
    MTRSubscribeAttribute<MTRUnitTestingBitmap8AttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeBitmap8WithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                       completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRUnitTestingBitmap8AttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(UnitTestingBitmap8AttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::Bitmap8::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBitmap16WithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::Bitmap16::TypeInfo;
    return MTRReadAttribute<MTRUnitTestingBitmap16AttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeBitmap16WithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeBitmap16WithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeBitmap16WithValue:(NSNumber * _Nonnull)value
                                 params:(MTRWriteParams * _Nullable)params
                             completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::Bitmap16::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = static_cast<std::remove_reference_t<decltype(cppValue)>>(value.unsignedShortValue);

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeBitmap16WithParams:(MTRSubscribeParams * _Nonnull)params
                     subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                               reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::Bitmap16::TypeInfo;
    MTRSubscribeAttribute<MTRUnitTestingBitmap16AttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeBitmap16WithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                        completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRUnitTestingBitmap16AttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(UnitTestingBitmap16AttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::Bitmap16::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBitmap32WithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::Bitmap32::TypeInfo;
    return MTRReadAttribute<MTRUnitTestingBitmap32AttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeBitmap32WithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeBitmap32WithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeBitmap32WithValue:(NSNumber * _Nonnull)value
                                 params:(MTRWriteParams * _Nullable)params
                             completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::Bitmap32::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = static_cast<std::remove_reference_t<decltype(cppValue)>>(value.unsignedIntValue);

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeBitmap32WithParams:(MTRSubscribeParams * _Nonnull)params
                     subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                               reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::Bitmap32::TypeInfo;
    MTRSubscribeAttribute<MTRUnitTestingBitmap32AttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeBitmap32WithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                        completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRUnitTestingBitmap32AttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(UnitTestingBitmap32AttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::Bitmap32::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBitmap64WithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::Bitmap64::TypeInfo;
    return MTRReadAttribute<MTRUnitTestingBitmap64AttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeBitmap64WithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeBitmap64WithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeBitmap64WithValue:(NSNumber * _Nonnull)value
                                 params:(MTRWriteParams * _Nullable)params
                             completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::Bitmap64::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = static_cast<std::remove_reference_t<decltype(cppValue)>>(value.unsignedLongLongValue);

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeBitmap64WithParams:(MTRSubscribeParams * _Nonnull)params
                     subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                               reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::Bitmap64::TypeInfo;
    MTRSubscribeAttribute<MTRUnitTestingBitmap64AttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeBitmap64WithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                        completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRUnitTestingBitmap64AttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(UnitTestingBitmap64AttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::Bitmap64::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeInt8uWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::Int8u::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeInt8uWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeInt8uWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeInt8uWithValue:(NSNumber * _Nonnull)value
                              params:(MTRWriteParams * _Nullable)params
                          completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::Int8u::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeInt8uWithParams:(MTRSubscribeParams * _Nonnull)params
                  subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                            reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::Int8u::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeInt8uWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                                     completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::Int8u::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeInt16uWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::Int16u::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeInt16uWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeInt16uWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeInt16uWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                           completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::Int16u::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeInt16uWithParams:(MTRSubscribeParams * _Nonnull)params
                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                             reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::Int16u::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeInt16uWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                                      completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::Int16u::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeInt24uWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::Int24u::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeInt24uWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeInt24uWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeInt24uWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                           completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::Int24u::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedIntValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeInt24uWithParams:(MTRSubscribeParams * _Nonnull)params
                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                             reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::Int24u::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeInt24uWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                                      completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::Int24u::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeInt32uWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::Int32u::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeInt32uWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeInt32uWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeInt32uWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                           completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::Int32u::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedIntValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeInt32uWithParams:(MTRSubscribeParams * _Nonnull)params
                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                             reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::Int32u::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeInt32uWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                                      completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::Int32u::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeInt40uWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::Int40u::TypeInfo;
    return MTRReadAttribute<MTRInt64uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeInt40uWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeInt40uWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeInt40uWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                           completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::Int40u::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedLongLongValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeInt40uWithParams:(MTRSubscribeParams * _Nonnull)params
                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                             reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::Int40u::TypeInfo;
    MTRSubscribeAttribute<MTRInt64uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeInt40uWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                                      completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt64uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int64uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::Int40u::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeInt48uWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::Int48u::TypeInfo;
    return MTRReadAttribute<MTRInt64uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeInt48uWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeInt48uWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeInt48uWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                           completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::Int48u::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedLongLongValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeInt48uWithParams:(MTRSubscribeParams * _Nonnull)params
                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                             reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::Int48u::TypeInfo;
    MTRSubscribeAttribute<MTRInt64uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeInt48uWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                                      completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt64uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int64uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::Int48u::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeInt56uWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::Int56u::TypeInfo;
    return MTRReadAttribute<MTRInt64uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeInt56uWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeInt56uWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeInt56uWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                           completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::Int56u::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedLongLongValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeInt56uWithParams:(MTRSubscribeParams * _Nonnull)params
                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                             reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::Int56u::TypeInfo;
    MTRSubscribeAttribute<MTRInt64uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeInt56uWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                                      completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt64uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int64uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::Int56u::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeInt64uWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::Int64u::TypeInfo;
    return MTRReadAttribute<MTRInt64uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeInt64uWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeInt64uWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeInt64uWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                           completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::Int64u::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedLongLongValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeInt64uWithParams:(MTRSubscribeParams * _Nonnull)params
                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                             reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::Int64u::TypeInfo;
    MTRSubscribeAttribute<MTRInt64uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeInt64uWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                                      completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt64uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int64uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::Int64u::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeInt8sWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::Int8s::TypeInfo;
    return MTRReadAttribute<MTRInt8sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeInt8sWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeInt8sWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeInt8sWithValue:(NSNumber * _Nonnull)value
                              params:(MTRWriteParams * _Nullable)params
                          completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::Int8s::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.charValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeInt8sWithParams:(MTRSubscribeParams * _Nonnull)params
                  subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                            reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::Int8s::TypeInfo;
    MTRSubscribeAttribute<MTRInt8sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeInt8sWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                                     completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::Int8s::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeInt16sWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::Int16s::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeInt16sWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeInt16sWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeInt16sWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                           completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::Int16s::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.shortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeInt16sWithParams:(MTRSubscribeParams * _Nonnull)params
                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                             reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::Int16s::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeInt16sWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                                      completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::Int16s::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeInt24sWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::Int24s::TypeInfo;
    return MTRReadAttribute<MTRInt32sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeInt24sWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeInt24sWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeInt24sWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                           completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::Int24s::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.intValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeInt24sWithParams:(MTRSubscribeParams * _Nonnull)params
                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                             reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::Int24s::TypeInfo;
    MTRSubscribeAttribute<MTRInt32sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeInt24sWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                                      completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::Int24s::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeInt32sWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::Int32s::TypeInfo;
    return MTRReadAttribute<MTRInt32sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeInt32sWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeInt32sWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeInt32sWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                           completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::Int32s::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.intValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeInt32sWithParams:(MTRSubscribeParams * _Nonnull)params
                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                             reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::Int32s::TypeInfo;
    MTRSubscribeAttribute<MTRInt32sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeInt32sWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                                      completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::Int32s::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeInt40sWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::Int40s::TypeInfo;
    return MTRReadAttribute<MTRInt64sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeInt40sWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeInt40sWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeInt40sWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                           completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::Int40s::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.longLongValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeInt40sWithParams:(MTRSubscribeParams * _Nonnull)params
                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                             reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::Int40s::TypeInfo;
    MTRSubscribeAttribute<MTRInt64sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeInt40sWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                                      completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt64sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int64sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::Int40s::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeInt48sWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::Int48s::TypeInfo;
    return MTRReadAttribute<MTRInt64sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeInt48sWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeInt48sWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeInt48sWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                           completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::Int48s::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.longLongValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeInt48sWithParams:(MTRSubscribeParams * _Nonnull)params
                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                             reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::Int48s::TypeInfo;
    MTRSubscribeAttribute<MTRInt64sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeInt48sWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                                      completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt64sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int64sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::Int48s::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeInt56sWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::Int56s::TypeInfo;
    return MTRReadAttribute<MTRInt64sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeInt56sWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeInt56sWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeInt56sWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                           completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::Int56s::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.longLongValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeInt56sWithParams:(MTRSubscribeParams * _Nonnull)params
                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                             reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::Int56s::TypeInfo;
    MTRSubscribeAttribute<MTRInt64sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeInt56sWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                                      completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt64sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int64sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::Int56s::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeInt64sWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::Int64s::TypeInfo;
    return MTRReadAttribute<MTRInt64sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeInt64sWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeInt64sWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeInt64sWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                           completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::Int64s::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.longLongValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeInt64sWithParams:(MTRSubscribeParams * _Nonnull)params
                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                             reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::Int64s::TypeInfo;
    MTRSubscribeAttribute<MTRInt64sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeInt64sWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                                      completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt64sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int64sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::Int64s::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEnum8WithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::Enum8::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeEnum8WithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeEnum8WithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeEnum8WithValue:(NSNumber * _Nonnull)value
                              params:(MTRWriteParams * _Nullable)params
                          completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::Enum8::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeEnum8WithParams:(MTRSubscribeParams * _Nonnull)params
                  subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                            reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::Enum8::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEnum8WithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                                     completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::Enum8::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEnum16WithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::Enum16::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeEnum16WithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeEnum16WithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeEnum16WithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                           completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::Enum16::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeEnum16WithParams:(MTRSubscribeParams * _Nonnull)params
                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                             reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::Enum16::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEnum16WithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                                      completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::Enum16::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFloatSingleWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::FloatSingle::TypeInfo;
    return MTRReadAttribute<MTRFloatAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeFloatSingleWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeFloatSingleWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeFloatSingleWithValue:(NSNumber * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                                completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::FloatSingle::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.floatValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeFloatSingleWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::FloatSingle::TypeInfo;
    MTRSubscribeAttribute<MTRFloatAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFloatSingleWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRFloatAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(FloatAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::FloatSingle::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFloatDoubleWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::FloatDouble::TypeInfo;
    return MTRReadAttribute<MTRDoubleAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeFloatDoubleWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeFloatDoubleWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeFloatDoubleWithValue:(NSNumber * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                                completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::FloatDouble::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.doubleValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeFloatDoubleWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::FloatDouble::TypeInfo;
    MTRSubscribeAttribute<MTRDoubleAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFloatDoubleWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRDoubleAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(DoubleAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::FloatDouble::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeOctetStringWithCompletion:(void (^)(NSData * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::OctetString::TypeInfo;
    return MTRReadAttribute<MTROctetStringAttributeCallbackBridge, NSData, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeOctetStringWithValue:(NSData * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeOctetStringWithValue:(NSData * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeOctetStringWithValue:(NSData * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                                completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::OctetString::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = [self asByteSpan:value];

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeOctetStringWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSData * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::OctetString::TypeInfo;
    MTRSubscribeAttribute<MTROctetStringAttributeCallbackSubscriptionBridge, NSData, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeOctetStringWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSData * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTROctetStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(OctetStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::OctetString::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeListInt8uWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::ListInt8u::TypeInfo;
    return MTRReadAttribute<MTRUnitTestingListInt8uListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeListInt8uWithValue:(NSArray * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeListInt8uWithValue:(NSArray * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeListInt8uWithValue:(NSArray * _Nonnull)value
                                  params:(MTRWriteParams * _Nullable)params
                              completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::ListInt8u::TypeInfo;
            TypeInfo::Type cppValue;
            {
                using ListType_0 = std::remove_reference_t<decltype(cppValue)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (value.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(value.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < value.count; ++i_0) {
                        if (![value[i_0] isKindOfClass:[NSNumber class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (NSNumber *) value[i_0];
                        listHolder_0->mList[i_0] = element_0.unsignedCharValue;
                    }
                    cppValue = ListType_0(listHolder_0->mList, value.count);
                } else {
                    cppValue = ListType_0();
                }
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeListInt8uWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::ListInt8u::TypeInfo;
    MTRSubscribeAttribute<MTRUnitTestingListInt8uListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeListInt8uWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRUnitTestingListInt8uListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(UnitTestingListInt8uListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::ListInt8u::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeListOctetStringWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::ListOctetString::TypeInfo;
    return MTRReadAttribute<MTRUnitTestingListOctetStringListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeListOctetStringWithValue:(NSArray * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeListOctetStringWithValue:(NSArray * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeListOctetStringWithValue:(NSArray * _Nonnull)value
                                        params:(MTRWriteParams * _Nullable)params
                                    completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::ListOctetString::TypeInfo;
            TypeInfo::Type cppValue;
            {
                using ListType_0 = std::remove_reference_t<decltype(cppValue)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (value.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(value.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < value.count; ++i_0) {
                        if (![value[i_0] isKindOfClass:[NSData class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (NSData *) value[i_0];
                        listHolder_0->mList[i_0] = [self asByteSpan:element_0];
                    }
                    cppValue = ListType_0(listHolder_0->mList, value.count);
                } else {
                    cppValue = ListType_0();
                }
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeListOctetStringWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::ListOctetString::TypeInfo;
    MTRSubscribeAttribute<MTRUnitTestingListOctetStringListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeListOctetStringWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRUnitTestingListOctetStringListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(UnitTestingListOctetStringListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::ListOctetString::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeListStructOctetStringWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::ListStructOctetString::TypeInfo;
    return MTRReadAttribute<MTRUnitTestingListStructOctetStringListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeListStructOctetStringWithValue:(NSArray * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeListStructOctetStringWithValue:(NSArray * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeListStructOctetStringWithValue:(NSArray * _Nonnull)value
                                              params:(MTRWriteParams * _Nullable)params
                                          completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::ListStructOctetString::TypeInfo;
            TypeInfo::Type cppValue;
            {
                using ListType_0 = std::remove_reference_t<decltype(cppValue)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (value.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(value.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < value.count; ++i_0) {
                        if (![value[i_0] isKindOfClass:[MTRUnitTestingClusterTestListStructOctet class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (MTRUnitTestingClusterTestListStructOctet *) value[i_0];
                        listHolder_0->mList[i_0].member1 = element_0.member1.unsignedLongLongValue;
                        listHolder_0->mList[i_0].member2 = [self asByteSpan:element_0.member2];
                    }
                    cppValue = ListType_0(listHolder_0->mList, value.count);
                } else {
                    cppValue = ListType_0();
                }
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeListStructOctetStringWithParams:(MTRSubscribeParams * _Nonnull)params
                                  subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                            reportHandler:
                                                (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::ListStructOctetString::TypeInfo;
    MTRSubscribeAttribute<MTRUnitTestingListStructOctetStringListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeListStructOctetStringWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                                     completion:
                                                         (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRUnitTestingListStructOctetStringListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(UnitTestingListStructOctetStringListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::ListStructOctetString::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeLongOctetStringWithCompletion:(void (^)(NSData * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::LongOctetString::TypeInfo;
    return MTRReadAttribute<MTROctetStringAttributeCallbackBridge, NSData, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeLongOctetStringWithValue:(NSData * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeLongOctetStringWithValue:(NSData * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeLongOctetStringWithValue:(NSData * _Nonnull)value
                                        params:(MTRWriteParams * _Nullable)params
                                    completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::LongOctetString::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = [self asByteSpan:value];

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeLongOctetStringWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSData * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::LongOctetString::TypeInfo;
    MTRSubscribeAttribute<MTROctetStringAttributeCallbackSubscriptionBridge, NSData, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeLongOctetStringWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:(void (^)(NSData * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTROctetStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(OctetStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::LongOctetString::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCharStringWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::CharString::TypeInfo;
    return MTRReadAttribute<MTRCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeCharStringWithValue:(NSString * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeCharStringWithValue:(NSString * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeCharStringWithValue:(NSString * _Nonnull)value
                                   params:(MTRWriteParams * _Nullable)params
                               completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::CharString::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = [self asCharSpan:value];

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeCharStringWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::CharString::TypeInfo;
    MTRSubscribeAttribute<MTRCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeCharStringWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(CharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::CharString::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeLongCharStringWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::LongCharString::TypeInfo;
    return MTRReadAttribute<MTRCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeLongCharStringWithValue:(NSString * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeLongCharStringWithValue:(NSString * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeLongCharStringWithValue:(NSString * _Nonnull)value
                                       params:(MTRWriteParams * _Nullable)params
                                   completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::LongCharString::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = [self asCharSpan:value];

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeLongCharStringWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::LongCharString::TypeInfo;
    MTRSubscribeAttribute<MTRCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeLongCharStringWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(CharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::LongCharString::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEpochUsWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::EpochUs::TypeInfo;
    return MTRReadAttribute<MTRInt64uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeEpochUsWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeEpochUsWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeEpochUsWithValue:(NSNumber * _Nonnull)value
                                params:(MTRWriteParams * _Nullable)params
                            completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::EpochUs::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedLongLongValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeEpochUsWithParams:(MTRSubscribeParams * _Nonnull)params
                    subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                              reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::EpochUs::TypeInfo;
    MTRSubscribeAttribute<MTRInt64uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEpochUsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                       completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt64uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int64uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::EpochUs::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEpochSWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::EpochS::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeEpochSWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeEpochSWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeEpochSWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                           completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::EpochS::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedIntValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeEpochSWithParams:(MTRSubscribeParams * _Nonnull)params
                   subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                             reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::EpochS::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEpochSWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                                      completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::EpochS::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeVendorIdWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::VendorId::TypeInfo;
    return MTRReadAttribute<MTRVendorIdAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeVendorIdWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeVendorIdWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeVendorIdWithValue:(NSNumber * _Nonnull)value
                                 params:(MTRWriteParams * _Nullable)params
                             completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::VendorId::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = static_cast<std::remove_reference_t<decltype(cppValue)>>(value.unsignedShortValue);

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeVendorIdWithParams:(MTRSubscribeParams * _Nonnull)params
                     subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                               reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::VendorId::TypeInfo;
    MTRSubscribeAttribute<MTRVendorIdAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeVendorIdWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                        completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRVendorIdAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(VendorIdAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::VendorId::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeListNullablesAndOptionalsStructWithCompletion:(void (^)(NSArray * _Nullable value,
                                                                       NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::ListNullablesAndOptionalsStruct::TypeInfo;
    return MTRReadAttribute<MTRUnitTestingListNullablesAndOptionalsStructListAttributeCallbackBridge, NSArray,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeListNullablesAndOptionalsStructWithValue:(NSArray * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeListNullablesAndOptionalsStructWithValue:(NSArray * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeListNullablesAndOptionalsStructWithValue:(NSArray * _Nonnull)value
                                                        params:(MTRWriteParams * _Nullable)params
                                                    completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::ListNullablesAndOptionalsStruct::TypeInfo;
            TypeInfo::Type cppValue;
            {
                using ListType_0 = std::remove_reference_t<decltype(cppValue)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (value.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(value.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < value.count; ++i_0) {
                        if (![value[i_0] isKindOfClass:[MTRUnitTestingClusterNullablesAndOptionalsStruct class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (MTRUnitTestingClusterNullablesAndOptionalsStruct *) value[i_0];
                        if (element_0.nullableInt == nil) {
                            listHolder_0->mList[i_0].nullableInt.SetNull();
                        } else {
                            auto & nonNullValue_2 = listHolder_0->mList[i_0].nullableInt.SetNonNull();
                            nonNullValue_2 = element_0.nullableInt.unsignedShortValue;
                        }
                        if (element_0.optionalInt != nil) {
                            auto & definedValue_2 = listHolder_0->mList[i_0].optionalInt.Emplace();
                            definedValue_2 = element_0.optionalInt.unsignedShortValue;
                        }
                        if (element_0.nullableOptionalInt != nil) {
                            auto & definedValue_2 = listHolder_0->mList[i_0].nullableOptionalInt.Emplace();
                            if (element_0.nullableOptionalInt == nil) {
                                definedValue_2.SetNull();
                            } else {
                                auto & nonNullValue_3 = definedValue_2.SetNonNull();
                                nonNullValue_3 = element_0.nullableOptionalInt.unsignedShortValue;
                            }
                        }
                        if (element_0.nullableString == nil) {
                            listHolder_0->mList[i_0].nullableString.SetNull();
                        } else {
                            auto & nonNullValue_2 = listHolder_0->mList[i_0].nullableString.SetNonNull();
                            nonNullValue_2 = [self asCharSpan:element_0.nullableString];
                        }
                        if (element_0.optionalString != nil) {
                            auto & definedValue_2 = listHolder_0->mList[i_0].optionalString.Emplace();
                            definedValue_2 = [self asCharSpan:element_0.optionalString];
                        }
                        if (element_0.nullableOptionalString != nil) {
                            auto & definedValue_2 = listHolder_0->mList[i_0].nullableOptionalString.Emplace();
                            if (element_0.nullableOptionalString == nil) {
                                definedValue_2.SetNull();
                            } else {
                                auto & nonNullValue_3 = definedValue_2.SetNonNull();
                                nonNullValue_3 = [self asCharSpan:element_0.nullableOptionalString];
                            }
                        }
                        if (element_0.nullableStruct == nil) {
                            listHolder_0->mList[i_0].nullableStruct.SetNull();
                        } else {
                            auto & nonNullValue_2 = listHolder_0->mList[i_0].nullableStruct.SetNonNull();
                            nonNullValue_2.a = element_0.nullableStruct.a.unsignedCharValue;
                            nonNullValue_2.b = element_0.nullableStruct.b.boolValue;
                            nonNullValue_2.c = static_cast<std::remove_reference_t<decltype(nonNullValue_2.c)>>(
                                element_0.nullableStruct.c.unsignedCharValue);
                            nonNullValue_2.d = [self asByteSpan:element_0.nullableStruct.d];
                            nonNullValue_2.e = [self asCharSpan:element_0.nullableStruct.e];
                            nonNullValue_2.f = static_cast<std::remove_reference_t<decltype(nonNullValue_2.f)>>(
                                element_0.nullableStruct.f.unsignedCharValue);
                            nonNullValue_2.g = element_0.nullableStruct.g.floatValue;
                            nonNullValue_2.h = element_0.nullableStruct.h.doubleValue;
                        }
                        if (element_0.optionalStruct != nil) {
                            auto & definedValue_2 = listHolder_0->mList[i_0].optionalStruct.Emplace();
                            definedValue_2.a = element_0.optionalStruct.a.unsignedCharValue;
                            definedValue_2.b = element_0.optionalStruct.b.boolValue;
                            definedValue_2.c = static_cast<std::remove_reference_t<decltype(definedValue_2.c)>>(
                                element_0.optionalStruct.c.unsignedCharValue);
                            definedValue_2.d = [self asByteSpan:element_0.optionalStruct.d];
                            definedValue_2.e = [self asCharSpan:element_0.optionalStruct.e];
                            definedValue_2.f = static_cast<std::remove_reference_t<decltype(definedValue_2.f)>>(
                                element_0.optionalStruct.f.unsignedCharValue);
                            definedValue_2.g = element_0.optionalStruct.g.floatValue;
                            definedValue_2.h = element_0.optionalStruct.h.doubleValue;
                        }
                        if (element_0.nullableOptionalStruct != nil) {
                            auto & definedValue_2 = listHolder_0->mList[i_0].nullableOptionalStruct.Emplace();
                            if (element_0.nullableOptionalStruct == nil) {
                                definedValue_2.SetNull();
                            } else {
                                auto & nonNullValue_3 = definedValue_2.SetNonNull();
                                nonNullValue_3.a = element_0.nullableOptionalStruct.a.unsignedCharValue;
                                nonNullValue_3.b = element_0.nullableOptionalStruct.b.boolValue;
                                nonNullValue_3.c = static_cast<std::remove_reference_t<decltype(nonNullValue_3.c)>>(
                                    element_0.nullableOptionalStruct.c.unsignedCharValue);
                                nonNullValue_3.d = [self asByteSpan:element_0.nullableOptionalStruct.d];
                                nonNullValue_3.e = [self asCharSpan:element_0.nullableOptionalStruct.e];
                                nonNullValue_3.f = static_cast<std::remove_reference_t<decltype(nonNullValue_3.f)>>(
                                    element_0.nullableOptionalStruct.f.unsignedCharValue);
                                nonNullValue_3.g = element_0.nullableOptionalStruct.g.floatValue;
                                nonNullValue_3.h = element_0.nullableOptionalStruct.h.doubleValue;
                            }
                        }
                        if (element_0.nullableList == nil) {
                            listHolder_0->mList[i_0].nullableList.SetNull();
                        } else {
                            auto & nonNullValue_2 = listHolder_0->mList[i_0].nullableList.SetNonNull();
                            {
                                using ListType_3 = std::remove_reference_t<decltype(nonNullValue_2)>;
                                using ListMemberType_3 = ListMemberTypeGetter<ListType_3>::Type;
                                if (element_0.nullableList.count != 0) {
                                    auto * listHolder_3 = new ListHolder<ListMemberType_3>(element_0.nullableList.count);
                                    if (listHolder_3 == nullptr || listHolder_3->mList == nullptr) {
                                        return CHIP_ERROR_INVALID_ARGUMENT;
                                    }
                                    listFreer.add(listHolder_3);
                                    for (size_t i_3 = 0; i_3 < element_0.nullableList.count; ++i_3) {
                                        if (![element_0.nullableList[i_3] isKindOfClass:[NSNumber class]]) {
                                            // Wrong kind of value.
                                            return CHIP_ERROR_INVALID_ARGUMENT;
                                        }
                                        auto element_3 = (NSNumber *) element_0.nullableList[i_3];
                                        listHolder_3->mList[i_3]
                                            = static_cast<std::remove_reference_t<decltype(listHolder_3->mList[i_3])>>(
                                                element_3.unsignedCharValue);
                                    }
                                    nonNullValue_2 = ListType_3(listHolder_3->mList, element_0.nullableList.count);
                                } else {
                                    nonNullValue_2 = ListType_3();
                                }
                            }
                        }
                        if (element_0.optionalList != nil) {
                            auto & definedValue_2 = listHolder_0->mList[i_0].optionalList.Emplace();
                            {
                                using ListType_3 = std::remove_reference_t<decltype(definedValue_2)>;
                                using ListMemberType_3 = ListMemberTypeGetter<ListType_3>::Type;
                                if (element_0.optionalList.count != 0) {
                                    auto * listHolder_3 = new ListHolder<ListMemberType_3>(element_0.optionalList.count);
                                    if (listHolder_3 == nullptr || listHolder_3->mList == nullptr) {
                                        return CHIP_ERROR_INVALID_ARGUMENT;
                                    }
                                    listFreer.add(listHolder_3);
                                    for (size_t i_3 = 0; i_3 < element_0.optionalList.count; ++i_3) {
                                        if (![element_0.optionalList[i_3] isKindOfClass:[NSNumber class]]) {
                                            // Wrong kind of value.
                                            return CHIP_ERROR_INVALID_ARGUMENT;
                                        }
                                        auto element_3 = (NSNumber *) element_0.optionalList[i_3];
                                        listHolder_3->mList[i_3]
                                            = static_cast<std::remove_reference_t<decltype(listHolder_3->mList[i_3])>>(
                                                element_3.unsignedCharValue);
                                    }
                                    definedValue_2 = ListType_3(listHolder_3->mList, element_0.optionalList.count);
                                } else {
                                    definedValue_2 = ListType_3();
                                }
                            }
                        }
                        if (element_0.nullableOptionalList != nil) {
                            auto & definedValue_2 = listHolder_0->mList[i_0].nullableOptionalList.Emplace();
                            if (element_0.nullableOptionalList == nil) {
                                definedValue_2.SetNull();
                            } else {
                                auto & nonNullValue_3 = definedValue_2.SetNonNull();
                                {
                                    using ListType_4 = std::remove_reference_t<decltype(nonNullValue_3)>;
                                    using ListMemberType_4 = ListMemberTypeGetter<ListType_4>::Type;
                                    if (element_0.nullableOptionalList.count != 0) {
                                        auto * listHolder_4
                                            = new ListHolder<ListMemberType_4>(element_0.nullableOptionalList.count);
                                        if (listHolder_4 == nullptr || listHolder_4->mList == nullptr) {
                                            return CHIP_ERROR_INVALID_ARGUMENT;
                                        }
                                        listFreer.add(listHolder_4);
                                        for (size_t i_4 = 0; i_4 < element_0.nullableOptionalList.count; ++i_4) {
                                            if (![element_0.nullableOptionalList[i_4] isKindOfClass:[NSNumber class]]) {
                                                // Wrong kind of value.
                                                return CHIP_ERROR_INVALID_ARGUMENT;
                                            }
                                            auto element_4 = (NSNumber *) element_0.nullableOptionalList[i_4];
                                            listHolder_4->mList[i_4]
                                                = static_cast<std::remove_reference_t<decltype(listHolder_4->mList[i_4])>>(
                                                    element_4.unsignedCharValue);
                                        }
                                        nonNullValue_3 = ListType_4(listHolder_4->mList, element_0.nullableOptionalList.count);
                                    } else {
                                        nonNullValue_3 = ListType_4();
                                    }
                                }
                            }
                        }
                    }
                    cppValue = ListType_0(listHolder_0->mList, value.count);
                } else {
                    cppValue = ListType_0();
                }
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeListNullablesAndOptionalsStructWithParams:(MTRSubscribeParams * _Nonnull)params
                                            subscriptionEstablished:
                                                (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                      reportHandler:(void (^)(NSArray * _Nullable value,
                                                                        NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::ListNullablesAndOptionalsStruct::TypeInfo;
    MTRSubscribeAttribute<MTRUnitTestingListNullablesAndOptionalsStructListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeListNullablesAndOptionalsStructWithClusterStateCache:
            (MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                                 endpoint:(NSNumber *)endpoint
                                                                    queue:(dispatch_queue_t)queue
                                                               completion:(void (^)(NSArray * _Nullable value,
                                                                              NSError * _Nullable error))completion
{
    auto * bridge = new MTRUnitTestingListNullablesAndOptionalsStructListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(UnitTestingListNullablesAndOptionalsStructListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::ListNullablesAndOptionalsStruct::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEnumAttrWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::EnumAttr::TypeInfo;
    return MTRReadAttribute<MTRUnitTestingClusterSimpleEnumAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeEnumAttrWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeEnumAttrWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeEnumAttrWithValue:(NSNumber * _Nonnull)value
                                 params:(MTRWriteParams * _Nullable)params
                             completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::EnumAttr::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = static_cast<std::remove_reference_t<decltype(cppValue)>>(value.unsignedCharValue);

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeEnumAttrWithParams:(MTRSubscribeParams * _Nonnull)params
                     subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                               reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::EnumAttr::TypeInfo;
    MTRSubscribeAttribute<MTRUnitTestingClusterSimpleEnumAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEnumAttrWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                        completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRUnitTestingClusterSimpleEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(UnitTestingClusterSimpleEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::EnumAttr::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeStructAttrWithCompletion:(void (^)(MTRUnitTestingClusterSimpleStruct * _Nullable value,
                                                  NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::StructAttr::TypeInfo;
    return MTRReadAttribute<MTRUnitTestingStructAttrStructAttributeCallbackBridge, MTRUnitTestingClusterSimpleStruct,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeStructAttrWithValue:(MTRUnitTestingClusterSimpleStruct * _Nonnull)value
                               completion:(MTRStatusCompletion)completion
{
    [self writeAttributeStructAttrWithValue:(MTRUnitTestingClusterSimpleStruct * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeStructAttrWithValue:(MTRUnitTestingClusterSimpleStruct * _Nonnull)value
                                   params:(MTRWriteParams * _Nullable)params
                               completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::StructAttr::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue.a = value.a.unsignedCharValue;
            cppValue.b = value.b.boolValue;
            cppValue.c = static_cast<std::remove_reference_t<decltype(cppValue.c)>>(value.c.unsignedCharValue);
            cppValue.d = [self asByteSpan:value.d];
            cppValue.e = [self asCharSpan:value.e];
            cppValue.f = static_cast<std::remove_reference_t<decltype(cppValue.f)>>(value.f.unsignedCharValue);
            cppValue.g = value.g.floatValue;
            cppValue.h = value.h.doubleValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeStructAttrWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(MTRUnitTestingClusterSimpleStruct * _Nullable value,
                                                   NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::StructAttr::TypeInfo;
    MTRSubscribeAttribute<MTRUnitTestingStructAttrStructAttributeCallbackSubscriptionBridge, MTRUnitTestingClusterSimpleStruct,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeStructAttrWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(MTRUnitTestingClusterSimpleStruct * _Nullable value,
                                                         NSError * _Nullable error))completion
{
    auto * bridge = new MTRUnitTestingStructAttrStructAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(UnitTestingStructAttrStructAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::StructAttr::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRangeRestrictedInt8uWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::RangeRestrictedInt8u::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeRangeRestrictedInt8uWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeRangeRestrictedInt8uWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeRangeRestrictedInt8uWithValue:(NSNumber * _Nonnull)value
                                             params:(MTRWriteParams * _Nullable)params
                                         completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::RangeRestrictedInt8u::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeRangeRestrictedInt8uWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::RangeRestrictedInt8u::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRangeRestrictedInt8uWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::RangeRestrictedInt8u::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRangeRestrictedInt8sWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::RangeRestrictedInt8s::TypeInfo;
    return MTRReadAttribute<MTRInt8sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeRangeRestrictedInt8sWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeRangeRestrictedInt8sWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeRangeRestrictedInt8sWithValue:(NSNumber * _Nonnull)value
                                             params:(MTRWriteParams * _Nullable)params
                                         completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::RangeRestrictedInt8s::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.charValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeRangeRestrictedInt8sWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::RangeRestrictedInt8s::TypeInfo;
    MTRSubscribeAttribute<MTRInt8sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRangeRestrictedInt8sWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::RangeRestrictedInt8s::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRangeRestrictedInt16uWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::RangeRestrictedInt16u::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeRangeRestrictedInt16uWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeRangeRestrictedInt16uWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeRangeRestrictedInt16uWithValue:(NSNumber * _Nonnull)value
                                              params:(MTRWriteParams * _Nullable)params
                                          completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::RangeRestrictedInt16u::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeRangeRestrictedInt16uWithParams:(MTRSubscribeParams * _Nonnull)params
                                  subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::RangeRestrictedInt16u::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRangeRestrictedInt16uWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                                     completion:
                                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::RangeRestrictedInt16u::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRangeRestrictedInt16sWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::RangeRestrictedInt16s::TypeInfo;
    return MTRReadAttribute<MTRInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeRangeRestrictedInt16sWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeRangeRestrictedInt16sWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeRangeRestrictedInt16sWithValue:(NSNumber * _Nonnull)value
                                              params:(MTRWriteParams * _Nullable)params
                                          completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::RangeRestrictedInt16s::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.shortValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeRangeRestrictedInt16sWithParams:(MTRSubscribeParams * _Nonnull)params
                                  subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::RangeRestrictedInt16s::TypeInfo;
    MTRSubscribeAttribute<MTRInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeRangeRestrictedInt16sWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                                     completion:
                                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::RangeRestrictedInt16s::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeListLongOctetStringWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::ListLongOctetString::TypeInfo;
    return MTRReadAttribute<MTRUnitTestingListLongOctetStringListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeListLongOctetStringWithValue:(NSArray * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeListLongOctetStringWithValue:(NSArray * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeListLongOctetStringWithValue:(NSArray * _Nonnull)value
                                            params:(MTRWriteParams * _Nullable)params
                                        completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::ListLongOctetString::TypeInfo;
            TypeInfo::Type cppValue;
            {
                using ListType_0 = std::remove_reference_t<decltype(cppValue)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (value.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(value.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < value.count; ++i_0) {
                        if (![value[i_0] isKindOfClass:[NSData class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (NSData *) value[i_0];
                        listHolder_0->mList[i_0] = [self asByteSpan:element_0];
                    }
                    cppValue = ListType_0(listHolder_0->mList, value.count);
                } else {
                    cppValue = ListType_0();
                }
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeListLongOctetStringWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::ListLongOctetString::TypeInfo;
    MTRSubscribeAttribute<MTRUnitTestingListLongOctetStringListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeListLongOctetStringWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRUnitTestingListLongOctetStringListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(UnitTestingListLongOctetStringListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::ListLongOctetString::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeListFabricScopedWithParams:(MTRReadParams * _Nullable)params
                                     completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{ // Make a copy of params before we go async.
    params = [params copy];
    using TypeInfo = UnitTesting::Attributes::ListFabricScoped::TypeInfo;
    return MTRReadAttribute<MTRUnitTestingListFabricScopedListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeListFabricScopedWithValue:(NSArray * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeListFabricScopedWithValue:(NSArray * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeListFabricScopedWithValue:(NSArray * _Nonnull)value
                                         params:(MTRWriteParams * _Nullable)params
                                     completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::ListFabricScoped::TypeInfo;
            TypeInfo::Type cppValue;
            {
                using ListType_0 = std::remove_reference_t<decltype(cppValue)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (value.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(value.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < value.count; ++i_0) {
                        if (![value[i_0] isKindOfClass:[MTRUnitTestingClusterTestFabricScoped class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (MTRUnitTestingClusterTestFabricScoped *) value[i_0];
                        listHolder_0->mList[i_0].fabricSensitiveInt8u = element_0.fabricSensitiveInt8u.unsignedCharValue;
                        if (element_0.optionalFabricSensitiveInt8u != nil) {
                            auto & definedValue_2 = listHolder_0->mList[i_0].optionalFabricSensitiveInt8u.Emplace();
                            definedValue_2 = element_0.optionalFabricSensitiveInt8u.unsignedCharValue;
                        }
                        if (element_0.nullableFabricSensitiveInt8u == nil) {
                            listHolder_0->mList[i_0].nullableFabricSensitiveInt8u.SetNull();
                        } else {
                            auto & nonNullValue_2 = listHolder_0->mList[i_0].nullableFabricSensitiveInt8u.SetNonNull();
                            nonNullValue_2 = element_0.nullableFabricSensitiveInt8u.unsignedCharValue;
                        }
                        if (element_0.nullableOptionalFabricSensitiveInt8u != nil) {
                            auto & definedValue_2 = listHolder_0->mList[i_0].nullableOptionalFabricSensitiveInt8u.Emplace();
                            if (element_0.nullableOptionalFabricSensitiveInt8u == nil) {
                                definedValue_2.SetNull();
                            } else {
                                auto & nonNullValue_3 = definedValue_2.SetNonNull();
                                nonNullValue_3 = element_0.nullableOptionalFabricSensitiveInt8u.unsignedCharValue;
                            }
                        }
                        listHolder_0->mList[i_0].fabricSensitiveCharString = [self asCharSpan:element_0.fabricSensitiveCharString];
                        listHolder_0->mList[i_0].fabricSensitiveStruct.a = element_0.fabricSensitiveStruct.a.unsignedCharValue;
                        listHolder_0->mList[i_0].fabricSensitiveStruct.b = element_0.fabricSensitiveStruct.b.boolValue;
                        listHolder_0->mList[i_0].fabricSensitiveStruct.c
                            = static_cast<std::remove_reference_t<decltype(listHolder_0->mList[i_0].fabricSensitiveStruct.c)>>(
                                element_0.fabricSensitiveStruct.c.unsignedCharValue);
                        listHolder_0->mList[i_0].fabricSensitiveStruct.d = [self asByteSpan:element_0.fabricSensitiveStruct.d];
                        listHolder_0->mList[i_0].fabricSensitiveStruct.e = [self asCharSpan:element_0.fabricSensitiveStruct.e];
                        listHolder_0->mList[i_0].fabricSensitiveStruct.f
                            = static_cast<std::remove_reference_t<decltype(listHolder_0->mList[i_0].fabricSensitiveStruct.f)>>(
                                element_0.fabricSensitiveStruct.f.unsignedCharValue);
                        listHolder_0->mList[i_0].fabricSensitiveStruct.g = element_0.fabricSensitiveStruct.g.floatValue;
                        listHolder_0->mList[i_0].fabricSensitiveStruct.h = element_0.fabricSensitiveStruct.h.doubleValue;
                        {
                            using ListType_2 = std::remove_reference_t<decltype(listHolder_0->mList[i_0].fabricSensitiveInt8uList)>;
                            using ListMemberType_2 = ListMemberTypeGetter<ListType_2>::Type;
                            if (element_0.fabricSensitiveInt8uList.count != 0) {
                                auto * listHolder_2 = new ListHolder<ListMemberType_2>(element_0.fabricSensitiveInt8uList.count);
                                if (listHolder_2 == nullptr || listHolder_2->mList == nullptr) {
                                    return CHIP_ERROR_INVALID_ARGUMENT;
                                }
                                listFreer.add(listHolder_2);
                                for (size_t i_2 = 0; i_2 < element_0.fabricSensitiveInt8uList.count; ++i_2) {
                                    if (![element_0.fabricSensitiveInt8uList[i_2] isKindOfClass:[NSNumber class]]) {
                                        // Wrong kind of value.
                                        return CHIP_ERROR_INVALID_ARGUMENT;
                                    }
                                    auto element_2 = (NSNumber *) element_0.fabricSensitiveInt8uList[i_2];
                                    listHolder_2->mList[i_2] = element_2.unsignedCharValue;
                                }
                                listHolder_0->mList[i_0].fabricSensitiveInt8uList
                                    = ListType_2(listHolder_2->mList, element_0.fabricSensitiveInt8uList.count);
                            } else {
                                listHolder_0->mList[i_0].fabricSensitiveInt8uList = ListType_2();
                            }
                        }
                        listHolder_0->mList[i_0].fabricIndex = element_0.fabricIndex.unsignedCharValue;
                    }
                    cppValue = ListType_0(listHolder_0->mList, value.count);
                } else {
                    cppValue = ListType_0();
                }
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeListFabricScopedWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::ListFabricScoped::TypeInfo;
    MTRSubscribeAttribute<MTRUnitTestingListFabricScopedListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeListFabricScopedWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRUnitTestingListFabricScopedListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(UnitTestingListFabricScopedListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::ListFabricScoped::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeTimedWriteBooleanWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::TimedWriteBoolean::TypeInfo;
    return MTRReadAttribute<MTRBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeTimedWriteBooleanWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeTimedWriteBooleanWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeTimedWriteBooleanWithValue:(NSNumber * _Nonnull)value
                                          params:(MTRWriteParams * _Nullable)params
                                      completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::TimedWriteBoolean::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.boolValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeTimedWriteBooleanWithParams:(MTRSubscribeParams * _Nonnull)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::TimedWriteBoolean::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeTimedWriteBooleanWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                                 completion:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::TimedWriteBoolean::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneralErrorBooleanWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::GeneralErrorBoolean::TypeInfo;
    return MTRReadAttribute<MTRBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeGeneralErrorBooleanWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeGeneralErrorBooleanWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeGeneralErrorBooleanWithValue:(NSNumber * _Nonnull)value
                                            params:(MTRWriteParams * _Nullable)params
                                        completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::GeneralErrorBoolean::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.boolValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeGeneralErrorBooleanWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::GeneralErrorBoolean::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneralErrorBooleanWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::GeneralErrorBoolean::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterErrorBooleanWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::ClusterErrorBoolean::TypeInfo;
    return MTRReadAttribute<MTRBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeClusterErrorBooleanWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeClusterErrorBooleanWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeClusterErrorBooleanWithValue:(NSNumber * _Nonnull)value
                                            params:(MTRWriteParams * _Nullable)params
                                        completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::ClusterErrorBoolean::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.boolValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeClusterErrorBooleanWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::ClusterErrorBoolean::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterErrorBooleanWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::ClusterErrorBoolean::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeUnsupportedWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::Unsupported::TypeInfo;
    return MTRReadAttribute<MTRBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeUnsupportedWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeUnsupportedWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeUnsupportedWithValue:(NSNumber * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                                completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::Unsupported::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.boolValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeUnsupportedWithParams:(MTRSubscribeParams * _Nonnull)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::Unsupported::TypeInfo;
    MTRSubscribeAttribute<MTRBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeUnsupportedWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                           completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(BooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::Unsupported::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNullableBooleanWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::NullableBoolean::TypeInfo;
    return MTRReadAttribute<MTRNullableBooleanAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeNullableBooleanWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeNullableBooleanWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeNullableBooleanWithValue:(NSNumber * _Nullable)value
                                        params:(MTRWriteParams * _Nullable)params
                                    completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::NullableBoolean::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.boolValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeNullableBooleanWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::NullableBoolean::TypeInfo;
    MTRSubscribeAttribute<MTRNullableBooleanAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNullableBooleanWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableBooleanAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableBooleanAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::NullableBoolean::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNullableBitmap8WithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::NullableBitmap8::TypeInfo;
    return MTRReadAttribute<MTRUnitTestingNullableBitmap8AttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeNullableBitmap8WithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeNullableBitmap8WithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeNullableBitmap8WithValue:(NSNumber * _Nullable)value
                                        params:(MTRWriteParams * _Nullable)params
                                    completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::NullableBitmap8::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = static_cast<std::remove_reference_t<decltype(nonNullValue_0)>>(value.unsignedCharValue);
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeNullableBitmap8WithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::NullableBitmap8::TypeInfo;
    MTRSubscribeAttribute<MTRUnitTestingNullableBitmap8AttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNullableBitmap8WithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRUnitTestingNullableBitmap8AttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(UnitTestingNullableBitmap8AttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::NullableBitmap8::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNullableBitmap16WithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::NullableBitmap16::TypeInfo;
    return MTRReadAttribute<MTRUnitTestingNullableBitmap16AttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeNullableBitmap16WithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeNullableBitmap16WithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeNullableBitmap16WithValue:(NSNumber * _Nullable)value
                                         params:(MTRWriteParams * _Nullable)params
                                     completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::NullableBitmap16::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = static_cast<std::remove_reference_t<decltype(nonNullValue_0)>>(value.unsignedShortValue);
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeNullableBitmap16WithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::NullableBitmap16::TypeInfo;
    MTRSubscribeAttribute<MTRUnitTestingNullableBitmap16AttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNullableBitmap16WithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRUnitTestingNullableBitmap16AttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(UnitTestingNullableBitmap16AttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::NullableBitmap16::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNullableBitmap32WithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::NullableBitmap32::TypeInfo;
    return MTRReadAttribute<MTRUnitTestingNullableBitmap32AttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeNullableBitmap32WithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeNullableBitmap32WithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeNullableBitmap32WithValue:(NSNumber * _Nullable)value
                                         params:(MTRWriteParams * _Nullable)params
                                     completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::NullableBitmap32::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = static_cast<std::remove_reference_t<decltype(nonNullValue_0)>>(value.unsignedIntValue);
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeNullableBitmap32WithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::NullableBitmap32::TypeInfo;
    MTRSubscribeAttribute<MTRUnitTestingNullableBitmap32AttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNullableBitmap32WithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRUnitTestingNullableBitmap32AttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(UnitTestingNullableBitmap32AttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::NullableBitmap32::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNullableBitmap64WithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::NullableBitmap64::TypeInfo;
    return MTRReadAttribute<MTRUnitTestingNullableBitmap64AttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeNullableBitmap64WithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeNullableBitmap64WithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeNullableBitmap64WithValue:(NSNumber * _Nullable)value
                                         params:(MTRWriteParams * _Nullable)params
                                     completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::NullableBitmap64::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = static_cast<std::remove_reference_t<decltype(nonNullValue_0)>>(value.unsignedLongLongValue);
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeNullableBitmap64WithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::NullableBitmap64::TypeInfo;
    MTRSubscribeAttribute<MTRUnitTestingNullableBitmap64AttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNullableBitmap64WithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRUnitTestingNullableBitmap64AttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(UnitTestingNullableBitmap64AttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::NullableBitmap64::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNullableInt8uWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::NullableInt8u::TypeInfo;
    return MTRReadAttribute<MTRNullableInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeNullableInt8uWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeNullableInt8uWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeNullableInt8uWithValue:(NSNumber * _Nullable)value
                                      params:(MTRWriteParams * _Nullable)params
                                  completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::NullableInt8u::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedCharValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeNullableInt8uWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::NullableInt8u::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNullableInt8uWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::NullableInt8u::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNullableInt16uWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::NullableInt16u::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeNullableInt16uWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeNullableInt16uWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeNullableInt16uWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                                   completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::NullableInt16u::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedShortValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeNullableInt16uWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::NullableInt16u::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNullableInt16uWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::NullableInt16u::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNullableInt24uWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::NullableInt24u::TypeInfo;
    return MTRReadAttribute<MTRNullableInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeNullableInt24uWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeNullableInt24uWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeNullableInt24uWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                                   completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::NullableInt24u::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedIntValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeNullableInt24uWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::NullableInt24u::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNullableInt24uWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::NullableInt24u::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNullableInt32uWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::NullableInt32u::TypeInfo;
    return MTRReadAttribute<MTRNullableInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeNullableInt32uWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeNullableInt32uWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeNullableInt32uWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                                   completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::NullableInt32u::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedIntValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeNullableInt32uWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::NullableInt32u::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNullableInt32uWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::NullableInt32u::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNullableInt40uWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::NullableInt40u::TypeInfo;
    return MTRReadAttribute<MTRNullableInt64uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeNullableInt40uWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeNullableInt40uWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeNullableInt40uWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                                   completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::NullableInt40u::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedLongLongValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeNullableInt40uWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::NullableInt40u::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt64uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNullableInt40uWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt64uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt64uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::NullableInt40u::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNullableInt48uWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::NullableInt48u::TypeInfo;
    return MTRReadAttribute<MTRNullableInt64uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeNullableInt48uWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeNullableInt48uWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeNullableInt48uWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                                   completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::NullableInt48u::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedLongLongValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeNullableInt48uWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::NullableInt48u::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt64uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNullableInt48uWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt64uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt64uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::NullableInt48u::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNullableInt56uWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::NullableInt56u::TypeInfo;
    return MTRReadAttribute<MTRNullableInt64uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeNullableInt56uWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeNullableInt56uWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeNullableInt56uWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                                   completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::NullableInt56u::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedLongLongValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeNullableInt56uWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::NullableInt56u::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt64uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNullableInt56uWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt64uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt64uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::NullableInt56u::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNullableInt64uWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::NullableInt64u::TypeInfo;
    return MTRReadAttribute<MTRNullableInt64uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeNullableInt64uWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeNullableInt64uWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeNullableInt64uWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                                   completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::NullableInt64u::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedLongLongValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeNullableInt64uWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::NullableInt64u::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt64uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNullableInt64uWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt64uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt64uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::NullableInt64u::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNullableInt8sWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::NullableInt8s::TypeInfo;
    return MTRReadAttribute<MTRNullableInt8sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeNullableInt8sWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeNullableInt8sWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeNullableInt8sWithValue:(NSNumber * _Nullable)value
                                      params:(MTRWriteParams * _Nullable)params
                                  completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::NullableInt8s::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.charValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeNullableInt8sWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::NullableInt8s::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt8sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNullableInt8sWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt8sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt8sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::NullableInt8s::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNullableInt16sWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::NullableInt16s::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeNullableInt16sWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeNullableInt16sWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeNullableInt16sWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                                   completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::NullableInt16s::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.shortValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeNullableInt16sWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::NullableInt16s::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNullableInt16sWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::NullableInt16s::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNullableInt24sWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::NullableInt24s::TypeInfo;
    return MTRReadAttribute<MTRNullableInt32sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeNullableInt24sWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeNullableInt24sWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeNullableInt24sWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                                   completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::NullableInt24s::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.intValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeNullableInt24sWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::NullableInt24s::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt32sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNullableInt24sWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt32sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt32sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::NullableInt24s::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNullableInt32sWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::NullableInt32s::TypeInfo;
    return MTRReadAttribute<MTRNullableInt32sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeNullableInt32sWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeNullableInt32sWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeNullableInt32sWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                                   completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::NullableInt32s::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.intValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeNullableInt32sWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::NullableInt32s::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt32sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNullableInt32sWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt32sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt32sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::NullableInt32s::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNullableInt40sWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::NullableInt40s::TypeInfo;
    return MTRReadAttribute<MTRNullableInt64sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeNullableInt40sWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeNullableInt40sWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeNullableInt40sWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                                   completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::NullableInt40s::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.longLongValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeNullableInt40sWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::NullableInt40s::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt64sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNullableInt40sWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt64sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt64sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::NullableInt40s::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNullableInt48sWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::NullableInt48s::TypeInfo;
    return MTRReadAttribute<MTRNullableInt64sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeNullableInt48sWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeNullableInt48sWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeNullableInt48sWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                                   completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::NullableInt48s::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.longLongValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeNullableInt48sWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::NullableInt48s::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt64sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNullableInt48sWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt64sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt64sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::NullableInt48s::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNullableInt56sWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::NullableInt56s::TypeInfo;
    return MTRReadAttribute<MTRNullableInt64sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeNullableInt56sWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeNullableInt56sWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeNullableInt56sWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                                   completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::NullableInt56s::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.longLongValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeNullableInt56sWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::NullableInt56s::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt64sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNullableInt56sWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt64sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt64sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::NullableInt56s::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNullableInt64sWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::NullableInt64s::TypeInfo;
    return MTRReadAttribute<MTRNullableInt64sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeNullableInt64sWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeNullableInt64sWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeNullableInt64sWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                                   completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::NullableInt64s::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.longLongValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeNullableInt64sWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::NullableInt64s::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt64sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNullableInt64sWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt64sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt64sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::NullableInt64s::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNullableEnum8WithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::NullableEnum8::TypeInfo;
    return MTRReadAttribute<MTRNullableInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeNullableEnum8WithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeNullableEnum8WithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeNullableEnum8WithValue:(NSNumber * _Nullable)value
                                      params:(MTRWriteParams * _Nullable)params
                                  completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::NullableEnum8::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedCharValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeNullableEnum8WithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::NullableEnum8::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNullableEnum8WithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::NullableEnum8::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNullableEnum16WithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::NullableEnum16::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeNullableEnum16WithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeNullableEnum16WithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeNullableEnum16WithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                                   completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::NullableEnum16::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedShortValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeNullableEnum16WithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::NullableEnum16::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNullableEnum16WithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::NullableEnum16::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNullableFloatSingleWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::NullableFloatSingle::TypeInfo;
    return MTRReadAttribute<MTRNullableFloatAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeNullableFloatSingleWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeNullableFloatSingleWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeNullableFloatSingleWithValue:(NSNumber * _Nullable)value
                                            params:(MTRWriteParams * _Nullable)params
                                        completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::NullableFloatSingle::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.floatValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeNullableFloatSingleWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::NullableFloatSingle::TypeInfo;
    MTRSubscribeAttribute<MTRNullableFloatAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNullableFloatSingleWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableFloatAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableFloatAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::NullableFloatSingle::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNullableFloatDoubleWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::NullableFloatDouble::TypeInfo;
    return MTRReadAttribute<MTRNullableDoubleAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeNullableFloatDoubleWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeNullableFloatDoubleWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeNullableFloatDoubleWithValue:(NSNumber * _Nullable)value
                                            params:(MTRWriteParams * _Nullable)params
                                        completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::NullableFloatDouble::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.doubleValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeNullableFloatDoubleWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::NullableFloatDouble::TypeInfo;
    MTRSubscribeAttribute<MTRNullableDoubleAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNullableFloatDoubleWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableDoubleAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableDoubleAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::NullableFloatDouble::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNullableOctetStringWithCompletion:(void (^)(NSData * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::NullableOctetString::TypeInfo;
    return MTRReadAttribute<MTRNullableOctetStringAttributeCallbackBridge, NSData, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeNullableOctetStringWithValue:(NSData * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeNullableOctetStringWithValue:(NSData * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeNullableOctetStringWithValue:(NSData * _Nullable)value
                                            params:(MTRWriteParams * _Nullable)params
                                        completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::NullableOctetString::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = [self asByteSpan:value];
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeNullableOctetStringWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:(void (^)(NSData * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::NullableOctetString::TypeInfo;
    MTRSubscribeAttribute<MTRNullableOctetStringAttributeCallbackSubscriptionBridge, NSData, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNullableOctetStringWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSData * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableOctetStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableOctetStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::NullableOctetString::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNullableCharStringWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::NullableCharString::TypeInfo;
    return MTRReadAttribute<MTRNullableCharStringAttributeCallbackBridge, NSString, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeNullableCharStringWithValue:(NSString * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeNullableCharStringWithValue:(NSString * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeNullableCharStringWithValue:(NSString * _Nullable)value
                                           params:(MTRWriteParams * _Nullable)params
                                       completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::NullableCharString::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = [self asCharSpan:value];
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeNullableCharStringWithParams:(MTRSubscribeParams * _Nonnull)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                         reportHandler:
                                             (void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::NullableCharString::TypeInfo;
    MTRSubscribeAttribute<MTRNullableCharStringAttributeCallbackSubscriptionBridge, NSString, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNullableCharStringWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                                  completion:
                                                      (void (^)(NSString * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableCharStringAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableCharStringAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::NullableCharString::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNullableEnumAttrWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::NullableEnumAttr::TypeInfo;
    return MTRReadAttribute<MTRNullableUnitTestingClusterSimpleEnumAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeNullableEnumAttrWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeNullableEnumAttrWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeNullableEnumAttrWithValue:(NSNumber * _Nullable)value
                                         params:(MTRWriteParams * _Nullable)params
                                     completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::NullableEnumAttr::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = static_cast<std::remove_reference_t<decltype(nonNullValue_0)>>(value.unsignedCharValue);
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeNullableEnumAttrWithParams:(MTRSubscribeParams * _Nonnull)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::NullableEnumAttr::TypeInfo;
    MTRSubscribeAttribute<MTRNullableUnitTestingClusterSimpleEnumAttributeCallbackSubscriptionBridge, NSNumber,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeNullableEnumAttrWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                                completion:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableUnitTestingClusterSimpleEnumAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(NullableUnitTestingClusterSimpleEnumAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::NullableEnumAttr::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNullableStructWithCompletion:(void (^)(MTRUnitTestingClusterSimpleStruct * _Nullable value,
                                                      NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::NullableStruct::TypeInfo;
    return MTRReadAttribute<MTRUnitTestingNullableStructStructAttributeCallbackBridge, MTRUnitTestingClusterSimpleStruct,
        TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeNullableStructWithValue:(MTRUnitTestingClusterSimpleStruct * _Nullable)value
                                   completion:(MTRStatusCompletion)completion
{
    [self writeAttributeNullableStructWithValue:(MTRUnitTestingClusterSimpleStruct * _Nullable) value
                                         params:nil
                                     completion:completion];
}
- (void)writeAttributeNullableStructWithValue:(MTRUnitTestingClusterSimpleStruct * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                                   completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::NullableStruct::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0.a = value.a.unsignedCharValue;
                nonNullValue_0.b = value.b.boolValue;
                nonNullValue_0.c = static_cast<std::remove_reference_t<decltype(nonNullValue_0.c)>>(value.c.unsignedCharValue);
                nonNullValue_0.d = [self asByteSpan:value.d];
                nonNullValue_0.e = [self asCharSpan:value.e];
                nonNullValue_0.f = static_cast<std::remove_reference_t<decltype(nonNullValue_0.f)>>(value.f.unsignedCharValue);
                nonNullValue_0.g = value.g.floatValue;
                nonNullValue_0.h = value.h.doubleValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeNullableStructWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(MTRUnitTestingClusterSimpleStruct * _Nullable value,
                                                       NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::NullableStruct::TypeInfo;
    MTRSubscribeAttribute<MTRUnitTestingNullableStructStructAttributeCallbackSubscriptionBridge, MTRUnitTestingClusterSimpleStruct,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeNullableStructWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(MTRUnitTestingClusterSimpleStruct * _Nullable value,
                                                             NSError * _Nullable error))completion
{
    auto * bridge = new MTRUnitTestingNullableStructStructAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(UnitTestingNullableStructStructAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::NullableStruct::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNullableRangeRestrictedInt8uWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::NullableRangeRestrictedInt8u::TypeInfo;
    return MTRReadAttribute<MTRNullableInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeNullableRangeRestrictedInt8uWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeNullableRangeRestrictedInt8uWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeNullableRangeRestrictedInt8uWithValue:(NSNumber * _Nullable)value
                                                     params:(MTRWriteParams * _Nullable)params
                                                 completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::NullableRangeRestrictedInt8u::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedCharValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeNullableRangeRestrictedInt8uWithParams:(MTRSubscribeParams * _Nonnull)params
                                         subscriptionEstablished:
                                             (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                   reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::NullableRangeRestrictedInt8u::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNullableRangeRestrictedInt8uWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                              endpoint:(NSNumber *)endpoint
                                                                 queue:(dispatch_queue_t)queue
                                                            completion:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::NullableRangeRestrictedInt8u::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNullableRangeRestrictedInt8sWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::NullableRangeRestrictedInt8s::TypeInfo;
    return MTRReadAttribute<MTRNullableInt8sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeNullableRangeRestrictedInt8sWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeNullableRangeRestrictedInt8sWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeNullableRangeRestrictedInt8sWithValue:(NSNumber * _Nullable)value
                                                     params:(MTRWriteParams * _Nullable)params
                                                 completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::NullableRangeRestrictedInt8s::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.charValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeNullableRangeRestrictedInt8sWithParams:(MTRSubscribeParams * _Nonnull)params
                                         subscriptionEstablished:
                                             (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                   reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::NullableRangeRestrictedInt8s::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt8sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNullableRangeRestrictedInt8sWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                              endpoint:(NSNumber *)endpoint
                                                                 queue:(dispatch_queue_t)queue
                                                            completion:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt8sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt8sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::NullableRangeRestrictedInt8s::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNullableRangeRestrictedInt16uWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::NullableRangeRestrictedInt16u::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeNullableRangeRestrictedInt16uWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeNullableRangeRestrictedInt16uWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeNullableRangeRestrictedInt16uWithValue:(NSNumber * _Nullable)value
                                                      params:(MTRWriteParams * _Nullable)params
                                                  completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::NullableRangeRestrictedInt16u::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedShortValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeNullableRangeRestrictedInt16uWithParams:(MTRSubscribeParams * _Nonnull)params
                                          subscriptionEstablished:
                                              (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                    reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::NullableRangeRestrictedInt16u::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNullableRangeRestrictedInt16uWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                               endpoint:(NSNumber *)endpoint
                                                                  queue:(dispatch_queue_t)queue
                                                             completion:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::NullableRangeRestrictedInt16u::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNullableRangeRestrictedInt16sWithCompletion:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::NullableRangeRestrictedInt16s::TypeInfo;
    return MTRReadAttribute<MTRNullableInt16sAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeNullableRangeRestrictedInt16sWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeNullableRangeRestrictedInt16sWithValue:(NSNumber * _Nullable) value params:nil completion:completion];
}
- (void)writeAttributeNullableRangeRestrictedInt16sWithValue:(NSNumber * _Nullable)value
                                                      params:(MTRWriteParams * _Nullable)params
                                                  completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::NullableRangeRestrictedInt16s::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.shortValue;
            }

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeNullableRangeRestrictedInt16sWithParams:(MTRSubscribeParams * _Nonnull)params
                                          subscriptionEstablished:
                                              (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                                    reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::NullableRangeRestrictedInt16s::TypeInfo;
    MTRSubscribeAttribute<MTRNullableInt16sAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeNullableRangeRestrictedInt16sWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                               endpoint:(NSNumber *)endpoint
                                                                  queue:(dispatch_queue_t)queue
                                                             completion:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))completion
{
    auto * bridge = new MTRNullableInt16sAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(NullableInt16sAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::NullableRangeRestrictedInt16s::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeWriteOnlyInt8uWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::WriteOnlyInt8u::TypeInfo;
    return MTRReadAttribute<MTRInt8uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)writeAttributeWriteOnlyInt8uWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion
{
    [self writeAttributeWriteOnlyInt8uWithValue:(NSNumber * _Nonnull) value params:nil completion:completion];
}
- (void)writeAttributeWriteOnlyInt8uWithValue:(NSNumber * _Nonnull)value
                                       params:(MTRWriteParams * _Nullable)params
                                   completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completion(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb,
            MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitTesting::Attributes::WriteOnlyInt8u::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;

            chip::Controller::ClusterBase cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
        });
    std::move(*bridge).DispatchAction(self.device);
}

- (void)subscribeAttributeWriteOnlyInt8uWithParams:(MTRSubscribeParams * _Nonnull)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::WriteOnlyInt8u::TypeInfo;
    MTRSubscribeAttribute<MTRInt8uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeWriteOnlyInt8uWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                              completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt8uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int8uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::WriteOnlyInt8u::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::GeneratedCommandList::TypeInfo;
    return MTRReadAttribute<MTRUnitTestingGeneratedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::GeneratedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRUnitTestingGeneratedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                                    completion:
                                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRUnitTestingGeneratedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(UnitTestingGeneratedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::AcceptedCommandList::TypeInfo;
    return MTRReadAttribute<MTRUnitTestingAcceptedCommandListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::AcceptedCommandList::TypeInfo;
    MTRSubscribeAttribute<MTRUnitTestingAcceptedCommandListListAttributeCallbackSubscriptionBridge, NSArray,
        TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint,
        TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                                   completion:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRUnitTestingAcceptedCommandListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(UnitTestingAcceptedCommandListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::EventList::TypeInfo;
    return MTRReadAttribute<MTRUnitTestingEventListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params
                      subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::EventList::TypeInfo;
    MTRSubscribeAttribute<MTRUnitTestingEventListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                         completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRUnitTestingEventListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(UnitTestingEventListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::EventList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::AttributeList::TypeInfo;
    return MTRReadAttribute<MTRUnitTestingAttributeListListAttributeCallbackBridge, NSArray, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::AttributeList::TypeInfo;
    MTRSubscribeAttribute<MTRUnitTestingAttributeListListAttributeCallbackSubscriptionBridge, NSArray, TypeInfo::DecodableType>(
        params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                             completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRUnitTestingAttributeListListAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(clusterStateCacheContainer.baseDevice,
        ^(UnitTestingAttributeListListAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::FeatureMap::TypeInfo;
    return MTRReadAttribute<MTRInt32uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::FeatureMap::TypeInfo;
    MTRSubscribeAttribute<MTRInt32uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                          completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt32uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int32uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::FeatureMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    MTRReadParams * params = [[MTRReadParams alloc] init];
    using TypeInfo = UnitTesting::Attributes::ClusterRevision::TypeInfo;
    return MTRReadAttribute<MTRInt16uAttributeCallbackBridge, NSNumber, TypeInfo::DecodableType>(
        params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = UnitTesting::Attributes::ClusterRevision::TypeInfo;
    MTRSubscribeAttribute<MTRInt16uAttributeCallbackSubscriptionBridge, NSNumber, TypeInfo::DecodableType>(params,
        subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(),
        TypeInfo::GetAttributeId());
}

+ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                               completion:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTRInt16uAttributeCallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(
        clusterStateCacheContainer.baseDevice, ^(Int16uAttributeCallback successCb, MTRErrorCallback failureCb) {
            if (clusterStateCacheContainer.cppClusterStateCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitTesting::Attributes::ClusterRevision::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
                if (err == CHIP_NO_ERROR) {
                    successCb(bridge, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

@end

@implementation MTRBaseClusterTestCluster
@end

@implementation MTRBaseClusterTestCluster (Deprecated)

- (void)testWithParams:(MTRTestClusterClusterTestParams * _Nullable)params completionHandler:(MTRStatusCompletion)completionHandler
{
    [self testWithParams:params completion:completionHandler];
}
- (void)testWithCompletionHandler:(MTRStatusCompletion)completionHandler
{
    [self testWithParams:nil completionHandler:completionHandler];
}
- (void)testNotHandledWithParams:(MTRTestClusterClusterTestNotHandledParams * _Nullable)params
               completionHandler:(MTRStatusCompletion)completionHandler
{
    [self testNotHandledWithParams:params completion:completionHandler];
}
- (void)testNotHandledWithCompletionHandler:(MTRStatusCompletion)completionHandler
{
    [self testNotHandledWithParams:nil completionHandler:completionHandler];
}
- (void)testSpecificWithParams:(MTRTestClusterClusterTestSpecificParams * _Nullable)params
             completionHandler:(void (^)(MTRTestClusterClusterTestSpecificResponseParams * _Nullable data,
                                   NSError * _Nullable error))completionHandler
{
    [self testSpecificWithParams:params
                      completion:^(MTRUnitTestingClusterTestSpecificResponseParams * _Nullable data, NSError * _Nullable error) {
                          // Cast is safe because subclass does not add any selectors.
                          completionHandler(static_cast<MTRTestClusterClusterTestSpecificResponseParams *>(data), error);
                      }];
}
- (void)testSpecificWithCompletionHandler:(void (^)(MTRTestClusterClusterTestSpecificResponseParams * _Nullable data,
                                              NSError * _Nullable error))completionHandler
{
    [self testSpecificWithParams:nil completionHandler:completionHandler];
}
- (void)testUnknownCommandWithParams:(MTRTestClusterClusterTestUnknownCommandParams * _Nullable)params
                   completionHandler:(MTRStatusCompletion)completionHandler
{
    [self testUnknownCommandWithParams:params completion:completionHandler];
}
- (void)testUnknownCommandWithCompletionHandler:(MTRStatusCompletion)completionHandler
{
    [self testUnknownCommandWithParams:nil completionHandler:completionHandler];
}
- (void)testAddArgumentsWithParams:(MTRTestClusterClusterTestAddArgumentsParams *)params
                 completionHandler:(void (^)(MTRTestClusterClusterTestAddArgumentsResponseParams * _Nullable data,
                                       NSError * _Nullable error))completionHandler
{
    [self testAddArgumentsWithParams:params
                          completion:^(
                              MTRUnitTestingClusterTestAddArgumentsResponseParams * _Nullable data, NSError * _Nullable error) {
                              // Cast is safe because subclass does not add any selectors.
                              completionHandler(static_cast<MTRTestClusterClusterTestAddArgumentsResponseParams *>(data), error);
                          }];
}
- (void)testSimpleArgumentRequestWithParams:(MTRTestClusterClusterTestSimpleArgumentRequestParams *)params
                          completionHandler:(void (^)(MTRTestClusterClusterTestSimpleArgumentResponseParams * _Nullable data,
                                                NSError * _Nullable error))completionHandler
{
    [self testSimpleArgumentRequestWithParams:params
                                   completion:^(MTRUnitTestingClusterTestSimpleArgumentResponseParams * _Nullable data,
                                       NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       completionHandler(
                                           static_cast<MTRTestClusterClusterTestSimpleArgumentResponseParams *>(data), error);
                                   }];
}
- (void)testStructArrayArgumentRequestWithParams:(MTRTestClusterClusterTestStructArrayArgumentRequestParams *)params
                               completionHandler:
                                   (void (^)(MTRTestClusterClusterTestStructArrayArgumentResponseParams * _Nullable data,
                                       NSError * _Nullable error))completionHandler
{
    [self testStructArrayArgumentRequestWithParams:params
                                        completion:^(MTRUnitTestingClusterTestStructArrayArgumentResponseParams * _Nullable data,
                                            NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            completionHandler(
                                                static_cast<MTRTestClusterClusterTestStructArrayArgumentResponseParams *>(data),
                                                error);
                                        }];
}
- (void)testStructArgumentRequestWithParams:(MTRTestClusterClusterTestStructArgumentRequestParams *)params
                          completionHandler:(void (^)(MTRTestClusterClusterBooleanResponseParams * _Nullable data,
                                                NSError * _Nullable error))completionHandler
{
    [self testStructArgumentRequestWithParams:params
                                   completion:^(
                                       MTRUnitTestingClusterBooleanResponseParams * _Nullable data, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       completionHandler(static_cast<MTRTestClusterClusterBooleanResponseParams *>(data), error);
                                   }];
}
- (void)testNestedStructArgumentRequestWithParams:(MTRTestClusterClusterTestNestedStructArgumentRequestParams *)params
                                completionHandler:(void (^)(MTRTestClusterClusterBooleanResponseParams * _Nullable data,
                                                      NSError * _Nullable error))completionHandler
{
    [self testNestedStructArgumentRequestWithParams:params
                                         completion:^(MTRUnitTestingClusterBooleanResponseParams * _Nullable data,
                                             NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             completionHandler(
                                                 static_cast<MTRTestClusterClusterBooleanResponseParams *>(data), error);
                                         }];
}
- (void)testListStructArgumentRequestWithParams:(MTRTestClusterClusterTestListStructArgumentRequestParams *)params
                              completionHandler:(void (^)(MTRTestClusterClusterBooleanResponseParams * _Nullable data,
                                                    NSError * _Nullable error))completionHandler
{
    [self
        testListStructArgumentRequestWithParams:params
                                     completion:^(
                                         MTRUnitTestingClusterBooleanResponseParams * _Nullable data, NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         completionHandler(static_cast<MTRTestClusterClusterBooleanResponseParams *>(data), error);
                                     }];
}
- (void)testListInt8UArgumentRequestWithParams:(MTRTestClusterClusterTestListInt8UArgumentRequestParams *)params
                             completionHandler:(void (^)(MTRTestClusterClusterBooleanResponseParams * _Nullable data,
                                                   NSError * _Nullable error))completionHandler
{
    [self testListInt8UArgumentRequestWithParams:params
                                      completion:^(
                                          MTRUnitTestingClusterBooleanResponseParams * _Nullable data, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          completionHandler(static_cast<MTRTestClusterClusterBooleanResponseParams *>(data), error);
                                      }];
}
- (void)testNestedStructListArgumentRequestWithParams:(MTRTestClusterClusterTestNestedStructListArgumentRequestParams *)params
                                    completionHandler:(void (^)(MTRTestClusterClusterBooleanResponseParams * _Nullable data,
                                                          NSError * _Nullable error))completionHandler
{
    [self testNestedStructListArgumentRequestWithParams:params
                                             completion:^(MTRUnitTestingClusterBooleanResponseParams * _Nullable data,
                                                 NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(
                                                     static_cast<MTRTestClusterClusterBooleanResponseParams *>(data), error);
                                             }];
}
- (void)testListNestedStructListArgumentRequestWithParams:
            (MTRTestClusterClusterTestListNestedStructListArgumentRequestParams *)params
                                        completionHandler:(void (^)(MTRTestClusterClusterBooleanResponseParams * _Nullable data,
                                                              NSError * _Nullable error))completionHandler
{
    [self testListNestedStructListArgumentRequestWithParams:params
                                                 completion:^(MTRUnitTestingClusterBooleanResponseParams * _Nullable data,
                                                     NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(
                                                         static_cast<MTRTestClusterClusterBooleanResponseParams *>(data), error);
                                                 }];
}
- (void)testListInt8UReverseRequestWithParams:(MTRTestClusterClusterTestListInt8UReverseRequestParams *)params
                            completionHandler:(void (^)(MTRTestClusterClusterTestListInt8UReverseResponseParams * _Nullable data,
                                                  NSError * _Nullable error))completionHandler
{
    [self testListInt8UReverseRequestWithParams:params
                                     completion:^(MTRUnitTestingClusterTestListInt8UReverseResponseParams * _Nullable data,
                                         NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         completionHandler(
                                             static_cast<MTRTestClusterClusterTestListInt8UReverseResponseParams *>(data), error);
                                     }];
}
- (void)testEnumsRequestWithParams:(MTRTestClusterClusterTestEnumsRequestParams *)params
                 completionHandler:(void (^)(MTRTestClusterClusterTestEnumsResponseParams * _Nullable data,
                                       NSError * _Nullable error))completionHandler
{
    [self testEnumsRequestWithParams:params
                          completion:^(MTRUnitTestingClusterTestEnumsResponseParams * _Nullable data, NSError * _Nullable error) {
                              // Cast is safe because subclass does not add any selectors.
                              completionHandler(static_cast<MTRTestClusterClusterTestEnumsResponseParams *>(data), error);
                          }];
}
- (void)testNullableOptionalRequestWithParams:(MTRTestClusterClusterTestNullableOptionalRequestParams * _Nullable)params
                            completionHandler:(void (^)(MTRTestClusterClusterTestNullableOptionalResponseParams * _Nullable data,
                                                  NSError * _Nullable error))completionHandler
{
    [self testNullableOptionalRequestWithParams:params
                                     completion:^(MTRUnitTestingClusterTestNullableOptionalResponseParams * _Nullable data,
                                         NSError * _Nullable error) {
                                         // Cast is safe because subclass does not add any selectors.
                                         completionHandler(
                                             static_cast<MTRTestClusterClusterTestNullableOptionalResponseParams *>(data), error);
                                     }];
}
- (void)testComplexNullableOptionalRequestWithParams:(MTRTestClusterClusterTestComplexNullableOptionalRequestParams *)params
                                   completionHandler:
                                       (void (^)(MTRTestClusterClusterTestComplexNullableOptionalResponseParams * _Nullable data,
                                           NSError * _Nullable error))completionHandler
{
    [self testComplexNullableOptionalRequestWithParams:params
                                            completion:^(
                                                MTRUnitTestingClusterTestComplexNullableOptionalResponseParams * _Nullable data,
                                                NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(
                                                    static_cast<MTRTestClusterClusterTestComplexNullableOptionalResponseParams *>(
                                                        data),
                                                    error);
                                            }];
}
- (void)simpleStructEchoRequestWithParams:(MTRTestClusterClusterSimpleStructEchoRequestParams *)params
                        completionHandler:(void (^)(MTRTestClusterClusterSimpleStructResponseParams * _Nullable data,
                                              NSError * _Nullable error))completionHandler
{
    [self simpleStructEchoRequestWithParams:params
                                 completion:^(
                                     MTRUnitTestingClusterSimpleStructResponseParams * _Nullable data, NSError * _Nullable error) {
                                     // Cast is safe because subclass does not add any selectors.
                                     completionHandler(static_cast<MTRTestClusterClusterSimpleStructResponseParams *>(data), error);
                                 }];
}
- (void)timedInvokeRequestWithParams:(MTRTestClusterClusterTimedInvokeRequestParams * _Nullable)params
                   completionHandler:(MTRStatusCompletion)completionHandler
{
    [self timedInvokeRequestWithParams:params completion:completionHandler];
}
- (void)timedInvokeRequestWithCompletionHandler:(MTRStatusCompletion)completionHandler
{
    [self timedInvokeRequestWithParams:nil completionHandler:completionHandler];
}
- (void)testSimpleOptionalArgumentRequestWithParams:(MTRTestClusterClusterTestSimpleOptionalArgumentRequestParams * _Nullable)params
                                  completionHandler:(MTRStatusCompletion)completionHandler
{
    [self testSimpleOptionalArgumentRequestWithParams:params completion:completionHandler];
}
- (void)testEmitTestEventRequestWithParams:(MTRTestClusterClusterTestEmitTestEventRequestParams *)params
                         completionHandler:(void (^)(MTRTestClusterClusterTestEmitTestEventResponseParams * _Nullable data,
                                               NSError * _Nullable error))completionHandler
{
    [self testEmitTestEventRequestWithParams:params
                                  completion:^(MTRUnitTestingClusterTestEmitTestEventResponseParams * _Nullable data,
                                      NSError * _Nullable error) {
                                      // Cast is safe because subclass does not add any selectors.
                                      completionHandler(
                                          static_cast<MTRTestClusterClusterTestEmitTestEventResponseParams *>(data), error);
                                  }];
}
- (void)testEmitTestFabricScopedEventRequestWithParams:(MTRTestClusterClusterTestEmitTestFabricScopedEventRequestParams *)params
                                     completionHandler:
                                         (void (^)(
                                             MTRTestClusterClusterTestEmitTestFabricScopedEventResponseParams * _Nullable data,
                                             NSError * _Nullable error))completionHandler
{
    [self
        testEmitTestFabricScopedEventRequestWithParams:params
                                            completion:^(
                                                MTRUnitTestingClusterTestEmitTestFabricScopedEventResponseParams * _Nullable data,
                                                NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(
                                                    static_cast<MTRTestClusterClusterTestEmitTestFabricScopedEventResponseParams *>(
                                                        data),
                                                    error);
                                            }];
}

- (void)readAttributeBooleanWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBooleanWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeBooleanWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeBooleanWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeBooleanWithValue:(NSNumber * _Nonnull)value
                                params:(MTRWriteParams * _Nullable)params
                     completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeBooleanWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeBooleanWithMinInterval:(NSNumber * _Nonnull)minInterval
                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                          params:(MTRSubscribeParams * _Nullable)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeBooleanWithParams:subscribeParams
                      subscriptionEstablished:subscriptionEstablishedHandler
                                reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                    // Cast is safe because subclass does not add any selectors.
                                    reportHandler(static_cast<NSNumber *>(value), error);
                                }];
}
+ (void)readAttributeBooleanWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                      endpoint:(NSNumber *)endpoint
                                         queue:(dispatch_queue_t)queue
                             completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBooleanWithClusterStateCache:attributeCacheContainer.realContainer
                                           endpoint:endpoint
                                              queue:queue
                                         completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             completionHandler(static_cast<NSNumber *>(value), error);
                                         }];
}

- (void)readAttributeBitmap8WithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBitmap8WithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeBitmap8WithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeBitmap8WithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeBitmap8WithValue:(NSNumber * _Nonnull)value
                                params:(MTRWriteParams * _Nullable)params
                     completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeBitmap8WithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeBitmap8WithMinInterval:(NSNumber * _Nonnull)minInterval
                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                          params:(MTRSubscribeParams * _Nullable)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeBitmap8WithParams:subscribeParams
                      subscriptionEstablished:subscriptionEstablishedHandler
                                reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                    // Cast is safe because subclass does not add any selectors.
                                    reportHandler(static_cast<NSNumber *>(value), error);
                                }];
}
+ (void)readAttributeBitmap8WithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                      endpoint:(NSNumber *)endpoint
                                         queue:(dispatch_queue_t)queue
                             completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBitmap8WithClusterStateCache:attributeCacheContainer.realContainer
                                           endpoint:endpoint
                                              queue:queue
                                         completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             completionHandler(static_cast<NSNumber *>(value), error);
                                         }];
}

- (void)readAttributeBitmap16WithCompletionHandler:(void (^)(
                                                       NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBitmap16WithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeBitmap16WithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeBitmap16WithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeBitmap16WithValue:(NSNumber * _Nonnull)value
                                 params:(MTRWriteParams * _Nullable)params
                      completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeBitmap16WithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeBitmap16WithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeBitmap16WithParams:subscribeParams
                       subscriptionEstablished:subscriptionEstablishedHandler
                                 reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                     // Cast is safe because subclass does not add any selectors.
                                     reportHandler(static_cast<NSNumber *>(value), error);
                                 }];
}
+ (void)readAttributeBitmap16WithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBitmap16WithClusterStateCache:attributeCacheContainer.realContainer
                                            endpoint:endpoint
                                               queue:queue
                                          completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              completionHandler(static_cast<NSNumber *>(value), error);
                                          }];
}

- (void)readAttributeBitmap32WithCompletionHandler:(void (^)(
                                                       NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBitmap32WithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeBitmap32WithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeBitmap32WithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeBitmap32WithValue:(NSNumber * _Nonnull)value
                                 params:(MTRWriteParams * _Nullable)params
                      completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeBitmap32WithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeBitmap32WithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeBitmap32WithParams:subscribeParams
                       subscriptionEstablished:subscriptionEstablishedHandler
                                 reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                     // Cast is safe because subclass does not add any selectors.
                                     reportHandler(static_cast<NSNumber *>(value), error);
                                 }];
}
+ (void)readAttributeBitmap32WithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBitmap32WithClusterStateCache:attributeCacheContainer.realContainer
                                            endpoint:endpoint
                                               queue:queue
                                          completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              completionHandler(static_cast<NSNumber *>(value), error);
                                          }];
}

- (void)readAttributeBitmap64WithCompletionHandler:(void (^)(
                                                       NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBitmap64WithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeBitmap64WithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeBitmap64WithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeBitmap64WithValue:(NSNumber * _Nonnull)value
                                 params:(MTRWriteParams * _Nullable)params
                      completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeBitmap64WithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeBitmap64WithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeBitmap64WithParams:subscribeParams
                       subscriptionEstablished:subscriptionEstablishedHandler
                                 reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                     // Cast is safe because subclass does not add any selectors.
                                     reportHandler(static_cast<NSNumber *>(value), error);
                                 }];
}
+ (void)readAttributeBitmap64WithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeBitmap64WithClusterStateCache:attributeCacheContainer.realContainer
                                            endpoint:endpoint
                                               queue:queue
                                          completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              completionHandler(static_cast<NSNumber *>(value), error);
                                          }];
}

- (void)readAttributeInt8uWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInt8uWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeInt8uWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeInt8uWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeInt8uWithValue:(NSNumber * _Nonnull)value
                              params:(MTRWriteParams * _Nullable)params
                   completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeInt8uWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeInt8uWithMinInterval:(NSNumber * _Nonnull)minInterval
                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                        params:(MTRSubscribeParams * _Nullable)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeInt8uWithParams:subscribeParams
                    subscriptionEstablished:subscriptionEstablishedHandler
                              reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                  // Cast is safe because subclass does not add any selectors.
                                  reportHandler(static_cast<NSNumber *>(value), error);
                              }];
}
+ (void)readAttributeInt8uWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                    endpoint:(NSNumber *)endpoint
                                       queue:(dispatch_queue_t)queue
                           completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInt8uWithClusterStateCache:attributeCacheContainer.realContainer
                                         endpoint:endpoint
                                            queue:queue
                                       completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           completionHandler(static_cast<NSNumber *>(value), error);
                                       }];
}

- (void)readAttributeInt16uWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInt16uWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeInt16uWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeInt16uWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeInt16uWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                    completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeInt16uWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeInt16uWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeInt16uWithParams:subscribeParams
                     subscriptionEstablished:subscriptionEstablishedHandler
                               reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                   // Cast is safe because subclass does not add any selectors.
                                   reportHandler(static_cast<NSNumber *>(value), error);
                               }];
}
+ (void)readAttributeInt16uWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInt16uWithClusterStateCache:attributeCacheContainer.realContainer
                                          endpoint:endpoint
                                             queue:queue
                                        completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            completionHandler(static_cast<NSNumber *>(value), error);
                                        }];
}

- (void)readAttributeInt24uWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInt24uWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeInt24uWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeInt24uWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeInt24uWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                    completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeInt24uWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeInt24uWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeInt24uWithParams:subscribeParams
                     subscriptionEstablished:subscriptionEstablishedHandler
                               reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                   // Cast is safe because subclass does not add any selectors.
                                   reportHandler(static_cast<NSNumber *>(value), error);
                               }];
}
+ (void)readAttributeInt24uWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInt24uWithClusterStateCache:attributeCacheContainer.realContainer
                                          endpoint:endpoint
                                             queue:queue
                                        completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            completionHandler(static_cast<NSNumber *>(value), error);
                                        }];
}

- (void)readAttributeInt32uWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInt32uWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeInt32uWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeInt32uWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeInt32uWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                    completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeInt32uWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeInt32uWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeInt32uWithParams:subscribeParams
                     subscriptionEstablished:subscriptionEstablishedHandler
                               reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                   // Cast is safe because subclass does not add any selectors.
                                   reportHandler(static_cast<NSNumber *>(value), error);
                               }];
}
+ (void)readAttributeInt32uWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInt32uWithClusterStateCache:attributeCacheContainer.realContainer
                                          endpoint:endpoint
                                             queue:queue
                                        completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            completionHandler(static_cast<NSNumber *>(value), error);
                                        }];
}

- (void)readAttributeInt40uWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInt40uWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeInt40uWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeInt40uWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeInt40uWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                    completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeInt40uWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeInt40uWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeInt40uWithParams:subscribeParams
                     subscriptionEstablished:subscriptionEstablishedHandler
                               reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                   // Cast is safe because subclass does not add any selectors.
                                   reportHandler(static_cast<NSNumber *>(value), error);
                               }];
}
+ (void)readAttributeInt40uWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInt40uWithClusterStateCache:attributeCacheContainer.realContainer
                                          endpoint:endpoint
                                             queue:queue
                                        completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            completionHandler(static_cast<NSNumber *>(value), error);
                                        }];
}

- (void)readAttributeInt48uWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInt48uWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeInt48uWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeInt48uWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeInt48uWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                    completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeInt48uWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeInt48uWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeInt48uWithParams:subscribeParams
                     subscriptionEstablished:subscriptionEstablishedHandler
                               reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                   // Cast is safe because subclass does not add any selectors.
                                   reportHandler(static_cast<NSNumber *>(value), error);
                               }];
}
+ (void)readAttributeInt48uWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInt48uWithClusterStateCache:attributeCacheContainer.realContainer
                                          endpoint:endpoint
                                             queue:queue
                                        completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            completionHandler(static_cast<NSNumber *>(value), error);
                                        }];
}

- (void)readAttributeInt56uWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInt56uWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeInt56uWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeInt56uWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeInt56uWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                    completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeInt56uWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeInt56uWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeInt56uWithParams:subscribeParams
                     subscriptionEstablished:subscriptionEstablishedHandler
                               reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                   // Cast is safe because subclass does not add any selectors.
                                   reportHandler(static_cast<NSNumber *>(value), error);
                               }];
}
+ (void)readAttributeInt56uWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInt56uWithClusterStateCache:attributeCacheContainer.realContainer
                                          endpoint:endpoint
                                             queue:queue
                                        completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            completionHandler(static_cast<NSNumber *>(value), error);
                                        }];
}

- (void)readAttributeInt64uWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInt64uWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeInt64uWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeInt64uWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeInt64uWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                    completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeInt64uWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeInt64uWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeInt64uWithParams:subscribeParams
                     subscriptionEstablished:subscriptionEstablishedHandler
                               reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                   // Cast is safe because subclass does not add any selectors.
                                   reportHandler(static_cast<NSNumber *>(value), error);
                               }];
}
+ (void)readAttributeInt64uWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInt64uWithClusterStateCache:attributeCacheContainer.realContainer
                                          endpoint:endpoint
                                             queue:queue
                                        completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            completionHandler(static_cast<NSNumber *>(value), error);
                                        }];
}

- (void)readAttributeInt8sWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInt8sWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeInt8sWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeInt8sWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeInt8sWithValue:(NSNumber * _Nonnull)value
                              params:(MTRWriteParams * _Nullable)params
                   completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeInt8sWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeInt8sWithMinInterval:(NSNumber * _Nonnull)minInterval
                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                        params:(MTRSubscribeParams * _Nullable)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeInt8sWithParams:subscribeParams
                    subscriptionEstablished:subscriptionEstablishedHandler
                              reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                  // Cast is safe because subclass does not add any selectors.
                                  reportHandler(static_cast<NSNumber *>(value), error);
                              }];
}
+ (void)readAttributeInt8sWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                    endpoint:(NSNumber *)endpoint
                                       queue:(dispatch_queue_t)queue
                           completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInt8sWithClusterStateCache:attributeCacheContainer.realContainer
                                         endpoint:endpoint
                                            queue:queue
                                       completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           completionHandler(static_cast<NSNumber *>(value), error);
                                       }];
}

- (void)readAttributeInt16sWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInt16sWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeInt16sWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeInt16sWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeInt16sWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                    completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeInt16sWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeInt16sWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeInt16sWithParams:subscribeParams
                     subscriptionEstablished:subscriptionEstablishedHandler
                               reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                   // Cast is safe because subclass does not add any selectors.
                                   reportHandler(static_cast<NSNumber *>(value), error);
                               }];
}
+ (void)readAttributeInt16sWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInt16sWithClusterStateCache:attributeCacheContainer.realContainer
                                          endpoint:endpoint
                                             queue:queue
                                        completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            completionHandler(static_cast<NSNumber *>(value), error);
                                        }];
}

- (void)readAttributeInt24sWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInt24sWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeInt24sWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeInt24sWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeInt24sWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                    completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeInt24sWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeInt24sWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeInt24sWithParams:subscribeParams
                     subscriptionEstablished:subscriptionEstablishedHandler
                               reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                   // Cast is safe because subclass does not add any selectors.
                                   reportHandler(static_cast<NSNumber *>(value), error);
                               }];
}
+ (void)readAttributeInt24sWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInt24sWithClusterStateCache:attributeCacheContainer.realContainer
                                          endpoint:endpoint
                                             queue:queue
                                        completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            completionHandler(static_cast<NSNumber *>(value), error);
                                        }];
}

- (void)readAttributeInt32sWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInt32sWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeInt32sWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeInt32sWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeInt32sWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                    completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeInt32sWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeInt32sWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeInt32sWithParams:subscribeParams
                     subscriptionEstablished:subscriptionEstablishedHandler
                               reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                   // Cast is safe because subclass does not add any selectors.
                                   reportHandler(static_cast<NSNumber *>(value), error);
                               }];
}
+ (void)readAttributeInt32sWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInt32sWithClusterStateCache:attributeCacheContainer.realContainer
                                          endpoint:endpoint
                                             queue:queue
                                        completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            completionHandler(static_cast<NSNumber *>(value), error);
                                        }];
}

- (void)readAttributeInt40sWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInt40sWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeInt40sWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeInt40sWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeInt40sWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                    completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeInt40sWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeInt40sWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeInt40sWithParams:subscribeParams
                     subscriptionEstablished:subscriptionEstablishedHandler
                               reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                   // Cast is safe because subclass does not add any selectors.
                                   reportHandler(static_cast<NSNumber *>(value), error);
                               }];
}
+ (void)readAttributeInt40sWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInt40sWithClusterStateCache:attributeCacheContainer.realContainer
                                          endpoint:endpoint
                                             queue:queue
                                        completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            completionHandler(static_cast<NSNumber *>(value), error);
                                        }];
}

- (void)readAttributeInt48sWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInt48sWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeInt48sWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeInt48sWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeInt48sWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                    completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeInt48sWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeInt48sWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeInt48sWithParams:subscribeParams
                     subscriptionEstablished:subscriptionEstablishedHandler
                               reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                   // Cast is safe because subclass does not add any selectors.
                                   reportHandler(static_cast<NSNumber *>(value), error);
                               }];
}
+ (void)readAttributeInt48sWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInt48sWithClusterStateCache:attributeCacheContainer.realContainer
                                          endpoint:endpoint
                                             queue:queue
                                        completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            completionHandler(static_cast<NSNumber *>(value), error);
                                        }];
}

- (void)readAttributeInt56sWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInt56sWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeInt56sWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeInt56sWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeInt56sWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                    completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeInt56sWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeInt56sWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeInt56sWithParams:subscribeParams
                     subscriptionEstablished:subscriptionEstablishedHandler
                               reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                   // Cast is safe because subclass does not add any selectors.
                                   reportHandler(static_cast<NSNumber *>(value), error);
                               }];
}
+ (void)readAttributeInt56sWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInt56sWithClusterStateCache:attributeCacheContainer.realContainer
                                          endpoint:endpoint
                                             queue:queue
                                        completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            completionHandler(static_cast<NSNumber *>(value), error);
                                        }];
}

- (void)readAttributeInt64sWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInt64sWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeInt64sWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeInt64sWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeInt64sWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                    completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeInt64sWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeInt64sWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeInt64sWithParams:subscribeParams
                     subscriptionEstablished:subscriptionEstablishedHandler
                               reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                   // Cast is safe because subclass does not add any selectors.
                                   reportHandler(static_cast<NSNumber *>(value), error);
                               }];
}
+ (void)readAttributeInt64sWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeInt64sWithClusterStateCache:attributeCacheContainer.realContainer
                                          endpoint:endpoint
                                             queue:queue
                                        completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            completionHandler(static_cast<NSNumber *>(value), error);
                                        }];
}

- (void)readAttributeEnum8WithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeEnum8WithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeEnum8WithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeEnum8WithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeEnum8WithValue:(NSNumber * _Nonnull)value
                              params:(MTRWriteParams * _Nullable)params
                   completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeEnum8WithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeEnum8WithMinInterval:(NSNumber * _Nonnull)minInterval
                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                        params:(MTRSubscribeParams * _Nullable)params
                       subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeEnum8WithParams:subscribeParams
                    subscriptionEstablished:subscriptionEstablishedHandler
                              reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                  // Cast is safe because subclass does not add any selectors.
                                  reportHandler(static_cast<NSNumber *>(value), error);
                              }];
}
+ (void)readAttributeEnum8WithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                    endpoint:(NSNumber *)endpoint
                                       queue:(dispatch_queue_t)queue
                           completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeEnum8WithClusterStateCache:attributeCacheContainer.realContainer
                                         endpoint:endpoint
                                            queue:queue
                                       completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           completionHandler(static_cast<NSNumber *>(value), error);
                                       }];
}

- (void)readAttributeEnum16WithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeEnum16WithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeEnum16WithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeEnum16WithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeEnum16WithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                    completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeEnum16WithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeEnum16WithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeEnum16WithParams:subscribeParams
                     subscriptionEstablished:subscriptionEstablishedHandler
                               reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                   // Cast is safe because subclass does not add any selectors.
                                   reportHandler(static_cast<NSNumber *>(value), error);
                               }];
}
+ (void)readAttributeEnum16WithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeEnum16WithClusterStateCache:attributeCacheContainer.realContainer
                                          endpoint:endpoint
                                             queue:queue
                                        completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            completionHandler(static_cast<NSNumber *>(value), error);
                                        }];
}

- (void)readAttributeFloatSingleWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFloatSingleWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeFloatSingleWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeFloatSingleWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeFloatSingleWithValue:(NSNumber * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                         completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeFloatSingleWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeFloatSingleWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFloatSingleWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSNumber *>(value), error);
                                    }];
}
+ (void)readAttributeFloatSingleWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFloatSingleWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                             }];
}

- (void)readAttributeFloatDoubleWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFloatDoubleWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeFloatDoubleWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeFloatDoubleWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeFloatDoubleWithValue:(NSNumber * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                         completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeFloatDoubleWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeFloatDoubleWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFloatDoubleWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSNumber *>(value), error);
                                    }];
}
+ (void)readAttributeFloatDoubleWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFloatDoubleWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                             }];
}

- (void)readAttributeOctetStringWithCompletionHandler:(void (^)(
                                                          NSData * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOctetStringWithCompletion:^(NSData * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSData *>(value), error);
    }];
}
- (void)writeAttributeOctetStringWithValue:(NSData * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeOctetStringWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeOctetStringWithValue:(NSData * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                         completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeOctetStringWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeOctetStringWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSData * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeOctetStringWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSData * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSData *>(value), error);
                                    }];
}
+ (void)readAttributeOctetStringWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:(void (^)(NSData * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeOctetStringWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSData * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSData *>(value), error);
                                             }];
}

- (void)readAttributeListInt8uWithCompletionHandler:(void (^)(
                                                        NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeListInt8uWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)writeAttributeListInt8uWithValue:(NSArray * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeListInt8uWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeListInt8uWithValue:(NSArray * _Nonnull)value
                                  params:(MTRWriteParams * _Nullable)params
                       completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeListInt8uWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeListInt8uWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeListInt8uWithParams:subscribeParams
                        subscriptionEstablished:subscriptionEstablishedHandler
                                  reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                      // Cast is safe because subclass does not add any selectors.
                                      reportHandler(static_cast<NSArray *>(value), error);
                                  }];
}
+ (void)readAttributeListInt8uWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeListInt8uWithClusterStateCache:attributeCacheContainer.realContainer
                                             endpoint:endpoint
                                                queue:queue
                                           completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               completionHandler(static_cast<NSArray *>(value), error);
                                           }];
}

- (void)readAttributeListOctetStringWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeListOctetStringWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)writeAttributeListOctetStringWithValue:(NSArray * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeListOctetStringWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeListOctetStringWithValue:(NSArray * _Nonnull)value
                                        params:(MTRWriteParams * _Nullable)params
                             completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeListOctetStringWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeListOctetStringWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeListOctetStringWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSArray *>(value), error);
                                        }];
}
+ (void)readAttributeListOctetStringWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeListOctetStringWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSArray *>(value), error);
                                                 }];
}

- (void)readAttributeListStructOctetStringWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    [self readAttributeListStructOctetStringWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)writeAttributeListStructOctetStringWithValue:(NSArray * _Nonnull)value
                                   completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeListStructOctetStringWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeListStructOctetStringWithValue:(NSArray * _Nonnull)value
                                              params:(MTRWriteParams * _Nullable)params
                                   completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeListStructOctetStringWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeListStructOctetStringWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeListStructOctetStringWithParams:subscribeParams
                                    subscriptionEstablished:subscriptionEstablishedHandler
                                              reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  reportHandler(static_cast<NSArray *>(value), error);
                                              }];
}
+ (void)readAttributeListStructOctetStringWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeListStructOctetStringWithClusterStateCache:attributeCacheContainer.realContainer
                                                         endpoint:endpoint
                                                            queue:queue
                                                       completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                           // Cast is safe because subclass does not add any selectors.
                                                           completionHandler(static_cast<NSArray *>(value), error);
                                                       }];
}

- (void)readAttributeLongOctetStringWithCompletionHandler:(void (^)(
                                                              NSData * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLongOctetStringWithCompletion:^(NSData * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSData *>(value), error);
    }];
}
- (void)writeAttributeLongOctetStringWithValue:(NSData * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeLongOctetStringWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeLongOctetStringWithValue:(NSData * _Nonnull)value
                                        params:(MTRWriteParams * _Nullable)params
                             completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeLongOctetStringWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeLongOctetStringWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSData * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeLongOctetStringWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSData * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSData *>(value), error);
                                        }];
}
+ (void)readAttributeLongOctetStringWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSData * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLongOctetStringWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSData * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSData *>(value), error);
                                                 }];
}

- (void)readAttributeCharStringWithCompletionHandler:(void (^)(
                                                         NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCharStringWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)writeAttributeCharStringWithValue:(NSString * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeCharStringWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeCharStringWithValue:(NSString * _Nonnull)value
                                   params:(MTRWriteParams * _Nullable)params
                        completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeCharStringWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeCharStringWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeCharStringWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSString *>(value), error);
                                   }];
}
+ (void)readAttributeCharStringWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeCharStringWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSString *>(value), error);
                                            }];
}

- (void)readAttributeLongCharStringWithCompletionHandler:(void (^)(NSString * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeLongCharStringWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)writeAttributeLongCharStringWithValue:(NSString * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeLongCharStringWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeLongCharStringWithValue:(NSString * _Nonnull)value
                                       params:(MTRWriteParams * _Nullable)params
                            completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeLongCharStringWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeLongCharStringWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeLongCharStringWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSString *>(value), error);
                                       }];
}
+ (void)readAttributeLongCharStringWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeLongCharStringWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSString *>(value), error);
                                                }];
}

- (void)readAttributeEpochUsWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeEpochUsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeEpochUsWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeEpochUsWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeEpochUsWithValue:(NSNumber * _Nonnull)value
                                params:(MTRWriteParams * _Nullable)params
                     completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeEpochUsWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeEpochUsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                          params:(MTRSubscribeParams * _Nullable)params
                         subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeEpochUsWithParams:subscribeParams
                      subscriptionEstablished:subscriptionEstablishedHandler
                                reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                    // Cast is safe because subclass does not add any selectors.
                                    reportHandler(static_cast<NSNumber *>(value), error);
                                }];
}
+ (void)readAttributeEpochUsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                      endpoint:(NSNumber *)endpoint
                                         queue:(dispatch_queue_t)queue
                             completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeEpochUsWithClusterStateCache:attributeCacheContainer.realContainer
                                           endpoint:endpoint
                                              queue:queue
                                         completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             completionHandler(static_cast<NSNumber *>(value), error);
                                         }];
}

- (void)readAttributeEpochSWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeEpochSWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeEpochSWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeEpochSWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeEpochSWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                    completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeEpochSWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeEpochSWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeEpochSWithParams:subscribeParams
                     subscriptionEstablished:subscriptionEstablishedHandler
                               reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                   // Cast is safe because subclass does not add any selectors.
                                   reportHandler(static_cast<NSNumber *>(value), error);
                               }];
}
+ (void)readAttributeEpochSWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeEpochSWithClusterStateCache:attributeCacheContainer.realContainer
                                          endpoint:endpoint
                                             queue:queue
                                        completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            completionHandler(static_cast<NSNumber *>(value), error);
                                        }];
}

- (void)readAttributeVendorIdWithCompletionHandler:(void (^)(
                                                       NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeVendorIdWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeVendorIdWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeVendorIdWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeVendorIdWithValue:(NSNumber * _Nonnull)value
                                 params:(MTRWriteParams * _Nullable)params
                      completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeVendorIdWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeVendorIdWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeVendorIdWithParams:subscribeParams
                       subscriptionEstablished:subscriptionEstablishedHandler
                                 reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                     // Cast is safe because subclass does not add any selectors.
                                     reportHandler(static_cast<NSNumber *>(value), error);
                                 }];
}
+ (void)readAttributeVendorIdWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeVendorIdWithClusterStateCache:attributeCacheContainer.realContainer
                                            endpoint:endpoint
                                               queue:queue
                                          completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              completionHandler(static_cast<NSNumber *>(value), error);
                                          }];
}

- (void)readAttributeListNullablesAndOptionalsStructWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeListNullablesAndOptionalsStructWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)writeAttributeListNullablesAndOptionalsStructWithValue:(NSArray * _Nonnull)value
                                             completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeListNullablesAndOptionalsStructWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeListNullablesAndOptionalsStructWithValue:(NSArray * _Nonnull)value
                                                        params:(MTRWriteParams * _Nullable)params
                                             completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeListNullablesAndOptionalsStructWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeListNullablesAndOptionalsStructWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                  params:(MTRSubscribeParams * _Nullable)params
                                                 subscriptionEstablished:
                                                     (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                           reportHandler:(void (^)(NSArray * _Nullable value,
                                                                             NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeListNullablesAndOptionalsStructWithParams:subscribeParams
                                              subscriptionEstablished:subscriptionEstablishedHandler
                                                        reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                            // Cast is safe because subclass does not add any selectors.
                                                            reportHandler(static_cast<NSArray *>(value), error);
                                                        }];
}
+ (void)readAttributeListNullablesAndOptionalsStructWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                              endpoint:(NSNumber *)endpoint
                                                                 queue:(dispatch_queue_t)queue
                                                     completionHandler:(void (^)(NSArray * _Nullable value,
                                                                           NSError * _Nullable error))completionHandler
{
    [self
        readAttributeListNullablesAndOptionalsStructWithClusterStateCache:attributeCacheContainer.realContainer
                                                                 endpoint:endpoint
                                                                    queue:queue
                                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                                   // Cast is safe because subclass does not add any selectors.
                                                                   completionHandler(static_cast<NSArray *>(value), error);
                                                               }];
}

- (void)readAttributeEnumAttrWithCompletionHandler:(void (^)(
                                                       NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeEnumAttrWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeEnumAttrWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeEnumAttrWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeEnumAttrWithValue:(NSNumber * _Nonnull)value
                                 params:(MTRWriteParams * _Nullable)params
                      completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeEnumAttrWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeEnumAttrWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeEnumAttrWithParams:subscribeParams
                       subscriptionEstablished:subscriptionEstablishedHandler
                                 reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                     // Cast is safe because subclass does not add any selectors.
                                     reportHandler(static_cast<NSNumber *>(value), error);
                                 }];
}
+ (void)readAttributeEnumAttrWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeEnumAttrWithClusterStateCache:attributeCacheContainer.realContainer
                                            endpoint:endpoint
                                               queue:queue
                                          completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              completionHandler(static_cast<NSNumber *>(value), error);
                                          }];
}

- (void)readAttributeStructAttrWithCompletionHandler:(void (^)(MTRTestClusterClusterSimpleStruct * _Nullable value,
                                                         NSError * _Nullable error))completionHandler
{
    [self readAttributeStructAttrWithCompletion:^(MTRUnitTestingClusterSimpleStruct * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<MTRTestClusterClusterSimpleStruct *>(value), error);
    }];
}
- (void)writeAttributeStructAttrWithValue:(MTRTestClusterClusterSimpleStruct * _Nonnull)value
                        completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeStructAttrWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeStructAttrWithValue:(MTRTestClusterClusterSimpleStruct * _Nonnull)value
                                   params:(MTRWriteParams * _Nullable)params
                        completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeStructAttrWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeStructAttrWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(MTRTestClusterClusterSimpleStruct * _Nullable value,
                                                        NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeStructAttrWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(MTRUnitTestingClusterSimpleStruct * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<MTRTestClusterClusterSimpleStruct *>(value), error);
                                   }];
}
+ (void)readAttributeStructAttrWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(MTRTestClusterClusterSimpleStruct * _Nullable value,
                                                      NSError * _Nullable error))completionHandler
{
    [self readAttributeStructAttrWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(
                                                MTRUnitTestingClusterSimpleStruct * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<MTRTestClusterClusterSimpleStruct *>(value), error);
                                            }];
}

- (void)readAttributeRangeRestrictedInt8uWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeRangeRestrictedInt8uWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeRangeRestrictedInt8uWithValue:(NSNumber * _Nonnull)value
                                  completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeRangeRestrictedInt8uWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeRangeRestrictedInt8uWithValue:(NSNumber * _Nonnull)value
                                             params:(MTRWriteParams * _Nullable)params
                                  completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeRangeRestrictedInt8uWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeRangeRestrictedInt8uWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRangeRestrictedInt8uWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSNumber *>(value), error);
                                             }];
}
+ (void)readAttributeRangeRestrictedInt8uWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRangeRestrictedInt8uWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSNumber *>(value), error);
                                                      }];
}

- (void)readAttributeRangeRestrictedInt8sWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeRangeRestrictedInt8sWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeRangeRestrictedInt8sWithValue:(NSNumber * _Nonnull)value
                                  completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeRangeRestrictedInt8sWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeRangeRestrictedInt8sWithValue:(NSNumber * _Nonnull)value
                                             params:(MTRWriteParams * _Nullable)params
                                  completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeRangeRestrictedInt8sWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeRangeRestrictedInt8sWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRangeRestrictedInt8sWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSNumber *>(value), error);
                                             }];
}
+ (void)readAttributeRangeRestrictedInt8sWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRangeRestrictedInt8sWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSNumber *>(value), error);
                                                      }];
}

- (void)readAttributeRangeRestrictedInt16uWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    [self readAttributeRangeRestrictedInt16uWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeRangeRestrictedInt16uWithValue:(NSNumber * _Nonnull)value
                                   completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeRangeRestrictedInt16uWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeRangeRestrictedInt16uWithValue:(NSNumber * _Nonnull)value
                                              params:(MTRWriteParams * _Nullable)params
                                   completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeRangeRestrictedInt16uWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeRangeRestrictedInt16uWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRangeRestrictedInt16uWithParams:subscribeParams
                                    subscriptionEstablished:subscriptionEstablishedHandler
                                              reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  reportHandler(static_cast<NSNumber *>(value), error);
                                              }];
}
+ (void)readAttributeRangeRestrictedInt16uWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRangeRestrictedInt16uWithClusterStateCache:attributeCacheContainer.realContainer
                                                         endpoint:endpoint
                                                            queue:queue
                                                       completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                           // Cast is safe because subclass does not add any selectors.
                                                           completionHandler(static_cast<NSNumber *>(value), error);
                                                       }];
}

- (void)readAttributeRangeRestrictedInt16sWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    [self readAttributeRangeRestrictedInt16sWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeRangeRestrictedInt16sWithValue:(NSNumber * _Nonnull)value
                                   completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeRangeRestrictedInt16sWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeRangeRestrictedInt16sWithValue:(NSNumber * _Nonnull)value
                                              params:(MTRWriteParams * _Nullable)params
                                   completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeRangeRestrictedInt16sWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeRangeRestrictedInt16sWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeRangeRestrictedInt16sWithParams:subscribeParams
                                    subscriptionEstablished:subscriptionEstablishedHandler
                                              reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  reportHandler(static_cast<NSNumber *>(value), error);
                                              }];
}
+ (void)readAttributeRangeRestrictedInt16sWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeRangeRestrictedInt16sWithClusterStateCache:attributeCacheContainer.realContainer
                                                         endpoint:endpoint
                                                            queue:queue
                                                       completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                           // Cast is safe because subclass does not add any selectors.
                                                           completionHandler(static_cast<NSNumber *>(value), error);
                                                       }];
}

- (void)readAttributeListLongOctetStringWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeListLongOctetStringWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)writeAttributeListLongOctetStringWithValue:(NSArray * _Nonnull)value
                                 completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeListLongOctetStringWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeListLongOctetStringWithValue:(NSArray * _Nonnull)value
                                            params:(MTRWriteParams * _Nullable)params
                                 completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeListLongOctetStringWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeListLongOctetStringWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeListLongOctetStringWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeListLongOctetStringWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeListLongOctetStringWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeListFabricScopedWithParams:(MTRReadParams * _Nullable)params
                              completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeListFabricScopedWithParams:params
                                       completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           completionHandler(static_cast<NSArray *>(value), error);
                                       }];
}
- (void)writeAttributeListFabricScopedWithValue:(NSArray * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeListFabricScopedWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeListFabricScopedWithValue:(NSArray * _Nonnull)value
                                         params:(MTRWriteParams * _Nullable)params
                              completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeListFabricScopedWithValue:value params:params completion:completionHandler];
}
- (void)
    subscribeAttributeListFabricScopedWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeListFabricScopedWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSArray *>(value), error);
                                         }];
}
+ (void)readAttributeListFabricScopedWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeListFabricScopedWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSArray *>(value), error);
                                                  }];
}

- (void)readAttributeTimedWriteBooleanWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    [self readAttributeTimedWriteBooleanWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeTimedWriteBooleanWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeTimedWriteBooleanWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeTimedWriteBooleanWithValue:(NSNumber * _Nonnull)value
                                          params:(MTRWriteParams * _Nullable)params
                               completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeTimedWriteBooleanWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeTimedWriteBooleanWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:
                                       (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeTimedWriteBooleanWithParams:subscribeParams
                                subscriptionEstablished:subscriptionEstablishedHandler
                                          reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                              // Cast is safe because subclass does not add any selectors.
                                              reportHandler(static_cast<NSNumber *>(value), error);
                                          }];
}
+ (void)readAttributeTimedWriteBooleanWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeTimedWriteBooleanWithClusterStateCache:attributeCacheContainer.realContainer
                                                     endpoint:endpoint
                                                        queue:queue
                                                   completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                       // Cast is safe because subclass does not add any selectors.
                                                       completionHandler(static_cast<NSNumber *>(value), error);
                                                   }];
}

- (void)readAttributeGeneralErrorBooleanWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneralErrorBooleanWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeGeneralErrorBooleanWithValue:(NSNumber * _Nonnull)value
                                 completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeGeneralErrorBooleanWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeGeneralErrorBooleanWithValue:(NSNumber * _Nonnull)value
                                            params:(MTRWriteParams * _Nullable)params
                                 completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeGeneralErrorBooleanWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeGeneralErrorBooleanWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneralErrorBooleanWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSNumber *>(value), error);
                                            }];
}
+ (void)readAttributeGeneralErrorBooleanWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneralErrorBooleanWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}

- (void)readAttributeClusterErrorBooleanWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterErrorBooleanWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeClusterErrorBooleanWithValue:(NSNumber * _Nonnull)value
                                 completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeClusterErrorBooleanWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeClusterErrorBooleanWithValue:(NSNumber * _Nonnull)value
                                            params:(MTRWriteParams * _Nullable)params
                                 completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeClusterErrorBooleanWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeClusterErrorBooleanWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterErrorBooleanWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSNumber *>(value), error);
                                            }];
}
+ (void)readAttributeClusterErrorBooleanWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterErrorBooleanWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}

- (void)readAttributeUnsupportedWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeUnsupportedWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeUnsupportedWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeUnsupportedWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeUnsupportedWithValue:(NSNumber * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                         completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeUnsupportedWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeUnsupportedWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeUnsupportedWithParams:subscribeParams
                          subscriptionEstablished:subscriptionEstablishedHandler
                                    reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                        // Cast is safe because subclass does not add any selectors.
                                        reportHandler(static_cast<NSNumber *>(value), error);
                                    }];
}
+ (void)readAttributeUnsupportedWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeUnsupportedWithClusterStateCache:attributeCacheContainer.realContainer
                                               endpoint:endpoint
                                                  queue:queue
                                             completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 completionHandler(static_cast<NSNumber *>(value), error);
                                             }];
}

- (void)readAttributeNullableBooleanWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableBooleanWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeNullableBooleanWithValue:(NSNumber * _Nullable)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableBooleanWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeNullableBooleanWithValue:(NSNumber * _Nullable)value
                                        params:(MTRWriteParams * _Nullable)params
                             completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableBooleanWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeNullableBooleanWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNullableBooleanWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeNullableBooleanWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableBooleanWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (void)readAttributeNullableBitmap8WithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableBitmap8WithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeNullableBitmap8WithValue:(NSNumber * _Nullable)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableBitmap8WithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeNullableBitmap8WithValue:(NSNumber * _Nullable)value
                                        params:(MTRWriteParams * _Nullable)params
                             completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableBitmap8WithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeNullableBitmap8WithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNullableBitmap8WithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeNullableBitmap8WithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableBitmap8WithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (void)readAttributeNullableBitmap16WithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableBitmap16WithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeNullableBitmap16WithValue:(NSNumber * _Nullable)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableBitmap16WithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeNullableBitmap16WithValue:(NSNumber * _Nullable)value
                                         params:(MTRWriteParams * _Nullable)params
                              completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableBitmap16WithValue:value params:params completion:completionHandler];
}
- (void)
    subscribeAttributeNullableBitmap16WithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNullableBitmap16WithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributeNullableBitmap16WithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableBitmap16WithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeNullableBitmap32WithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableBitmap32WithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeNullableBitmap32WithValue:(NSNumber * _Nullable)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableBitmap32WithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeNullableBitmap32WithValue:(NSNumber * _Nullable)value
                                         params:(MTRWriteParams * _Nullable)params
                              completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableBitmap32WithValue:value params:params completion:completionHandler];
}
- (void)
    subscribeAttributeNullableBitmap32WithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNullableBitmap32WithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributeNullableBitmap32WithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableBitmap32WithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeNullableBitmap64WithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableBitmap64WithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeNullableBitmap64WithValue:(NSNumber * _Nullable)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableBitmap64WithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeNullableBitmap64WithValue:(NSNumber * _Nullable)value
                                         params:(MTRWriteParams * _Nullable)params
                              completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableBitmap64WithValue:value params:params completion:completionHandler];
}
- (void)
    subscribeAttributeNullableBitmap64WithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNullableBitmap64WithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributeNullableBitmap64WithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableBitmap64WithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeNullableInt8uWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableInt8uWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeNullableInt8uWithValue:(NSNumber * _Nullable)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableInt8uWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeNullableInt8uWithValue:(NSNumber * _Nullable)value
                                      params:(MTRWriteParams * _Nullable)params
                           completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableInt8uWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeNullableInt8uWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNullableInt8uWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributeNullableInt8uWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableInt8uWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributeNullableInt16uWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableInt16uWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeNullableInt16uWithValue:(NSNumber * _Nullable)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableInt16uWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeNullableInt16uWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                            completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableInt16uWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeNullableInt16uWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNullableInt16uWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSNumber *>(value), error);
                                       }];
}
+ (void)readAttributeNullableInt16uWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableInt16uWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSNumber *>(value), error);
                                                }];
}

- (void)readAttributeNullableInt24uWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableInt24uWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeNullableInt24uWithValue:(NSNumber * _Nullable)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableInt24uWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeNullableInt24uWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                            completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableInt24uWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeNullableInt24uWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNullableInt24uWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSNumber *>(value), error);
                                       }];
}
+ (void)readAttributeNullableInt24uWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableInt24uWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSNumber *>(value), error);
                                                }];
}

- (void)readAttributeNullableInt32uWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableInt32uWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeNullableInt32uWithValue:(NSNumber * _Nullable)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableInt32uWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeNullableInt32uWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                            completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableInt32uWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeNullableInt32uWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNullableInt32uWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSNumber *>(value), error);
                                       }];
}
+ (void)readAttributeNullableInt32uWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableInt32uWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSNumber *>(value), error);
                                                }];
}

- (void)readAttributeNullableInt40uWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableInt40uWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeNullableInt40uWithValue:(NSNumber * _Nullable)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableInt40uWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeNullableInt40uWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                            completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableInt40uWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeNullableInt40uWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNullableInt40uWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSNumber *>(value), error);
                                       }];
}
+ (void)readAttributeNullableInt40uWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableInt40uWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSNumber *>(value), error);
                                                }];
}

- (void)readAttributeNullableInt48uWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableInt48uWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeNullableInt48uWithValue:(NSNumber * _Nullable)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableInt48uWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeNullableInt48uWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                            completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableInt48uWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeNullableInt48uWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNullableInt48uWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSNumber *>(value), error);
                                       }];
}
+ (void)readAttributeNullableInt48uWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableInt48uWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSNumber *>(value), error);
                                                }];
}

- (void)readAttributeNullableInt56uWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableInt56uWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeNullableInt56uWithValue:(NSNumber * _Nullable)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableInt56uWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeNullableInt56uWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                            completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableInt56uWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeNullableInt56uWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNullableInt56uWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSNumber *>(value), error);
                                       }];
}
+ (void)readAttributeNullableInt56uWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableInt56uWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSNumber *>(value), error);
                                                }];
}

- (void)readAttributeNullableInt64uWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableInt64uWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeNullableInt64uWithValue:(NSNumber * _Nullable)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableInt64uWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeNullableInt64uWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                            completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableInt64uWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeNullableInt64uWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNullableInt64uWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSNumber *>(value), error);
                                       }];
}
+ (void)readAttributeNullableInt64uWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableInt64uWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSNumber *>(value), error);
                                                }];
}

- (void)readAttributeNullableInt8sWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableInt8sWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeNullableInt8sWithValue:(NSNumber * _Nullable)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableInt8sWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeNullableInt8sWithValue:(NSNumber * _Nullable)value
                                      params:(MTRWriteParams * _Nullable)params
                           completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableInt8sWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeNullableInt8sWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNullableInt8sWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributeNullableInt8sWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableInt8sWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributeNullableInt16sWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableInt16sWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeNullableInt16sWithValue:(NSNumber * _Nullable)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableInt16sWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeNullableInt16sWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                            completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableInt16sWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeNullableInt16sWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNullableInt16sWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSNumber *>(value), error);
                                       }];
}
+ (void)readAttributeNullableInt16sWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableInt16sWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSNumber *>(value), error);
                                                }];
}

- (void)readAttributeNullableInt24sWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableInt24sWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeNullableInt24sWithValue:(NSNumber * _Nullable)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableInt24sWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeNullableInt24sWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                            completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableInt24sWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeNullableInt24sWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNullableInt24sWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSNumber *>(value), error);
                                       }];
}
+ (void)readAttributeNullableInt24sWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableInt24sWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSNumber *>(value), error);
                                                }];
}

- (void)readAttributeNullableInt32sWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableInt32sWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeNullableInt32sWithValue:(NSNumber * _Nullable)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableInt32sWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeNullableInt32sWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                            completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableInt32sWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeNullableInt32sWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNullableInt32sWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSNumber *>(value), error);
                                       }];
}
+ (void)readAttributeNullableInt32sWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableInt32sWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSNumber *>(value), error);
                                                }];
}

- (void)readAttributeNullableInt40sWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableInt40sWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeNullableInt40sWithValue:(NSNumber * _Nullable)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableInt40sWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeNullableInt40sWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                            completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableInt40sWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeNullableInt40sWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNullableInt40sWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSNumber *>(value), error);
                                       }];
}
+ (void)readAttributeNullableInt40sWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableInt40sWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSNumber *>(value), error);
                                                }];
}

- (void)readAttributeNullableInt48sWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableInt48sWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeNullableInt48sWithValue:(NSNumber * _Nullable)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableInt48sWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeNullableInt48sWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                            completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableInt48sWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeNullableInt48sWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNullableInt48sWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSNumber *>(value), error);
                                       }];
}
+ (void)readAttributeNullableInt48sWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableInt48sWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSNumber *>(value), error);
                                                }];
}

- (void)readAttributeNullableInt56sWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableInt56sWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeNullableInt56sWithValue:(NSNumber * _Nullable)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableInt56sWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeNullableInt56sWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                            completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableInt56sWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeNullableInt56sWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNullableInt56sWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSNumber *>(value), error);
                                       }];
}
+ (void)readAttributeNullableInt56sWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableInt56sWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSNumber *>(value), error);
                                                }];
}

- (void)readAttributeNullableInt64sWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableInt64sWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeNullableInt64sWithValue:(NSNumber * _Nullable)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableInt64sWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeNullableInt64sWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                            completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableInt64sWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeNullableInt64sWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNullableInt64sWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSNumber *>(value), error);
                                       }];
}
+ (void)readAttributeNullableInt64sWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableInt64sWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSNumber *>(value), error);
                                                }];
}

- (void)readAttributeNullableEnum8WithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableEnum8WithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeNullableEnum8WithValue:(NSNumber * _Nullable)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableEnum8WithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeNullableEnum8WithValue:(NSNumber * _Nullable)value
                                      params:(MTRWriteParams * _Nullable)params
                           completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableEnum8WithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeNullableEnum8WithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNullableEnum8WithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSNumber *>(value), error);
                                      }];
}
+ (void)readAttributeNullableEnum8WithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableEnum8WithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                               }];
}

- (void)readAttributeNullableEnum16WithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableEnum16WithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeNullableEnum16WithValue:(NSNumber * _Nullable)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableEnum16WithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeNullableEnum16WithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                            completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableEnum16WithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeNullableEnum16WithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNullableEnum16WithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSNumber *>(value), error);
                                       }];
}
+ (void)readAttributeNullableEnum16WithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableEnum16WithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSNumber *>(value), error);
                                                }];
}

- (void)readAttributeNullableFloatSingleWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableFloatSingleWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeNullableFloatSingleWithValue:(NSNumber * _Nullable)value
                                 completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableFloatSingleWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeNullableFloatSingleWithValue:(NSNumber * _Nullable)value
                                            params:(MTRWriteParams * _Nullable)params
                                 completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableFloatSingleWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeNullableFloatSingleWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNullableFloatSingleWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSNumber *>(value), error);
                                            }];
}
+ (void)readAttributeNullableFloatSingleWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableFloatSingleWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}

- (void)readAttributeNullableFloatDoubleWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableFloatDoubleWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeNullableFloatDoubleWithValue:(NSNumber * _Nullable)value
                                 completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableFloatDoubleWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeNullableFloatDoubleWithValue:(NSNumber * _Nullable)value
                                            params:(MTRWriteParams * _Nullable)params
                                 completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableFloatDoubleWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeNullableFloatDoubleWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNullableFloatDoubleWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSNumber *>(value), error);
                                            }];
}
+ (void)readAttributeNullableFloatDoubleWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableFloatDoubleWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}

- (void)readAttributeNullableOctetStringWithCompletionHandler:(void (^)(NSData * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableOctetStringWithCompletion:^(NSData * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSData *>(value), error);
    }];
}
- (void)writeAttributeNullableOctetStringWithValue:(NSData * _Nullable)value
                                 completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableOctetStringWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeNullableOctetStringWithValue:(NSData * _Nullable)value
                                            params:(MTRWriteParams * _Nullable)params
                                 completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableOctetStringWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeNullableOctetStringWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSData * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNullableOctetStringWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSData * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSData *>(value), error);
                                            }];
}
+ (void)readAttributeNullableOctetStringWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSData * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableOctetStringWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSData * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSData *>(value), error);
                                                     }];
}

- (void)readAttributeNullableCharStringWithCompletionHandler:(void (^)(NSString * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableCharStringWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSString *>(value), error);
    }];
}
- (void)writeAttributeNullableCharStringWithValue:(NSString * _Nullable)value
                                completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableCharStringWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeNullableCharStringWithValue:(NSString * _Nullable)value
                                           params:(MTRWriteParams * _Nullable)params
                                completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableCharStringWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeNullableCharStringWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:
                                        (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNullableCharStringWithParams:subscribeParams
                                 subscriptionEstablished:subscriptionEstablishedHandler
                                           reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                                               // Cast is safe because subclass does not add any selectors.
                                               reportHandler(static_cast<NSString *>(value), error);
                                           }];
}
+ (void)readAttributeNullableCharStringWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableCharStringWithClusterStateCache:attributeCacheContainer.realContainer
                                                      endpoint:endpoint
                                                         queue:queue
                                                    completion:^(NSString * _Nullable value, NSError * _Nullable error) {
                                                        // Cast is safe because subclass does not add any selectors.
                                                        completionHandler(static_cast<NSString *>(value), error);
                                                    }];
}

- (void)readAttributeNullableEnumAttrWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableEnumAttrWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeNullableEnumAttrWithValue:(NSNumber * _Nullable)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableEnumAttrWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeNullableEnumAttrWithValue:(NSNumber * _Nullable)value
                                         params:(MTRWriteParams * _Nullable)params
                              completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableEnumAttrWithValue:value params:params completion:completionHandler];
}
- (void)
    subscribeAttributeNullableEnumAttrWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNullableEnumAttrWithParams:subscribeParams
                               subscriptionEstablished:subscriptionEstablishedHandler
                                         reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                             // Cast is safe because subclass does not add any selectors.
                                             reportHandler(static_cast<NSNumber *>(value), error);
                                         }];
}
+ (void)readAttributeNullableEnumAttrWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableEnumAttrWithClusterStateCache:attributeCacheContainer.realContainer
                                                    endpoint:endpoint
                                                       queue:queue
                                                  completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                      // Cast is safe because subclass does not add any selectors.
                                                      completionHandler(static_cast<NSNumber *>(value), error);
                                                  }];
}

- (void)readAttributeNullableStructWithCompletionHandler:(void (^)(MTRTestClusterClusterSimpleStruct * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableStructWithCompletion:^(
        MTRUnitTestingClusterSimpleStruct * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<MTRTestClusterClusterSimpleStruct *>(value), error);
    }];
}
- (void)writeAttributeNullableStructWithValue:(MTRTestClusterClusterSimpleStruct * _Nullable)value
                            completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableStructWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeNullableStructWithValue:(MTRTestClusterClusterSimpleStruct * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                            completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableStructWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeNullableStructWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:(void (^)(MTRTestClusterClusterSimpleStruct * _Nullable value,
                                                            NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNullableStructWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(
                                           MTRUnitTestingClusterSimpleStruct * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<MTRTestClusterClusterSimpleStruct *>(value), error);
                                       }];
}
+ (void)readAttributeNullableStructWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:(void (^)(MTRTestClusterClusterSimpleStruct * _Nullable value,
                                                          NSError * _Nullable error))completionHandler
{
    [self
        readAttributeNullableStructWithClusterStateCache:attributeCacheContainer.realContainer
                                                endpoint:endpoint
                                                   queue:queue
                                              completion:^(
                                                  MTRUnitTestingClusterSimpleStruct * _Nullable value, NSError * _Nullable error) {
                                                  // Cast is safe because subclass does not add any selectors.
                                                  completionHandler(static_cast<MTRTestClusterClusterSimpleStruct *>(value), error);
                                              }];
}

- (void)readAttributeNullableRangeRestrictedInt8uWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableRangeRestrictedInt8uWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeNullableRangeRestrictedInt8uWithValue:(NSNumber * _Nullable)value
                                          completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableRangeRestrictedInt8uWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeNullableRangeRestrictedInt8uWithValue:(NSNumber * _Nullable)value
                                                     params:(MTRWriteParams * _Nullable)params
                                          completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableRangeRestrictedInt8uWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeNullableRangeRestrictedInt8uWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                                               params:(MTRSubscribeParams * _Nullable)params
                                              subscriptionEstablished:
                                                  (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                        reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNullableRangeRestrictedInt8uWithParams:subscribeParams
                                           subscriptionEstablished:subscriptionEstablishedHandler
                                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         reportHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}
+ (void)readAttributeNullableRangeRestrictedInt8uWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                           endpoint:(NSNumber *)endpoint
                                                              queue:(dispatch_queue_t)queue
                                                  completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableRangeRestrictedInt8uWithClusterStateCache:attributeCacheContainer.realContainer
                                                                endpoint:endpoint
                                                                   queue:queue
                                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                  // Cast is safe because subclass does not add any selectors.
                                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                                              }];
}

- (void)readAttributeNullableRangeRestrictedInt8sWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableRangeRestrictedInt8sWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeNullableRangeRestrictedInt8sWithValue:(NSNumber * _Nullable)value
                                          completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableRangeRestrictedInt8sWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeNullableRangeRestrictedInt8sWithValue:(NSNumber * _Nullable)value
                                                     params:(MTRWriteParams * _Nullable)params
                                          completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableRangeRestrictedInt8sWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeNullableRangeRestrictedInt8sWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                                               params:(MTRSubscribeParams * _Nullable)params
                                              subscriptionEstablished:
                                                  (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                        reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNullableRangeRestrictedInt8sWithParams:subscribeParams
                                           subscriptionEstablished:subscriptionEstablishedHandler
                                                     reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         reportHandler(static_cast<NSNumber *>(value), error);
                                                     }];
}
+ (void)readAttributeNullableRangeRestrictedInt8sWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                           endpoint:(NSNumber *)endpoint
                                                              queue:(dispatch_queue_t)queue
                                                  completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableRangeRestrictedInt8sWithClusterStateCache:attributeCacheContainer.realContainer
                                                                endpoint:endpoint
                                                                   queue:queue
                                                              completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                  // Cast is safe because subclass does not add any selectors.
                                                                  completionHandler(static_cast<NSNumber *>(value), error);
                                                              }];
}

- (void)readAttributeNullableRangeRestrictedInt16uWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableRangeRestrictedInt16uWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeNullableRangeRestrictedInt16uWithValue:(NSNumber * _Nullable)value
                                           completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableRangeRestrictedInt16uWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeNullableRangeRestrictedInt16uWithValue:(NSNumber * _Nullable)value
                                                      params:(MTRWriteParams * _Nullable)params
                                           completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableRangeRestrictedInt16uWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeNullableRangeRestrictedInt16uWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                params:(MTRSubscribeParams * _Nullable)params
                                               subscriptionEstablished:
                                                   (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                         reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNullableRangeRestrictedInt16uWithParams:subscribeParams
                                            subscriptionEstablished:subscriptionEstablishedHandler
                                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          reportHandler(static_cast<NSNumber *>(value), error);
                                                      }];
}
+ (void)readAttributeNullableRangeRestrictedInt16uWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                            endpoint:(NSNumber *)endpoint
                                                               queue:(dispatch_queue_t)queue
                                                   completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableRangeRestrictedInt16uWithClusterStateCache:attributeCacheContainer.realContainer
                                                                 endpoint:endpoint
                                                                    queue:queue
                                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                   // Cast is safe because subclass does not add any selectors.
                                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                                               }];
}

- (void)readAttributeNullableRangeRestrictedInt16sWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableRangeRestrictedInt16sWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeNullableRangeRestrictedInt16sWithValue:(NSNumber * _Nullable)value
                                           completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableRangeRestrictedInt16sWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeNullableRangeRestrictedInt16sWithValue:(NSNumber * _Nullable)value
                                                      params:(MTRWriteParams * _Nullable)params
                                           completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeNullableRangeRestrictedInt16sWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeNullableRangeRestrictedInt16sWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                params:(MTRSubscribeParams * _Nullable)params
                                               subscriptionEstablished:
                                                   (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                         reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeNullableRangeRestrictedInt16sWithParams:subscribeParams
                                            subscriptionEstablished:subscriptionEstablishedHandler
                                                      reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          reportHandler(static_cast<NSNumber *>(value), error);
                                                      }];
}
+ (void)readAttributeNullableRangeRestrictedInt16sWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                            endpoint:(NSNumber *)endpoint
                                                               queue:(dispatch_queue_t)queue
                                                   completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    [self readAttributeNullableRangeRestrictedInt16sWithClusterStateCache:attributeCacheContainer.realContainer
                                                                 endpoint:endpoint
                                                                    queue:queue
                                                               completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                                   // Cast is safe because subclass does not add any selectors.
                                                                   completionHandler(static_cast<NSNumber *>(value), error);
                                                               }];
}

- (void)readAttributeWriteOnlyInt8uWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    [self readAttributeWriteOnlyInt8uWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)writeAttributeWriteOnlyInt8uWithValue:(NSNumber * _Nonnull)value completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeWriteOnlyInt8uWithValue:value params:nil completion:completionHandler];
}
- (void)writeAttributeWriteOnlyInt8uWithValue:(NSNumber * _Nonnull)value
                                       params:(MTRWriteParams * _Nullable)params
                            completionHandler:(MTRStatusCompletion)completionHandler
{
    [self writeAttributeWriteOnlyInt8uWithValue:value params:params completion:completionHandler];
}
- (void)subscribeAttributeWriteOnlyInt8uWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeWriteOnlyInt8uWithParams:subscribeParams
                             subscriptionEstablished:subscriptionEstablishedHandler
                                       reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                           // Cast is safe because subclass does not add any selectors.
                                           reportHandler(static_cast<NSNumber *>(value), error);
                                       }];
}
+ (void)readAttributeWriteOnlyInt8uWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeWriteOnlyInt8uWithClusterStateCache:attributeCacheContainer.realContainer
                                                  endpoint:endpoint
                                                     queue:queue
                                                completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                    // Cast is safe because subclass does not add any selectors.
                                                    completionHandler(static_cast<NSNumber *>(value), error);
                                                }];
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeGeneratedCommandListWithParams:subscribeParams
                                   subscriptionEstablished:subscriptionEstablishedHandler
                                             reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                 // Cast is safe because subclass does not add any selectors.
                                                 reportHandler(static_cast<NSArray *>(value), error);
                                             }];
}
+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeGeneratedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                        endpoint:endpoint
                                                           queue:queue
                                                      completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                          // Cast is safe because subclass does not add any selectors.
                                                          completionHandler(static_cast<NSArray *>(value), error);
                                                      }];
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAcceptedCommandListWithParams:subscribeParams
                                  subscriptionEstablished:subscriptionEstablishedHandler
                                            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                reportHandler(static_cast<NSArray *>(value), error);
                                            }];
}
+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAcceptedCommandListWithClusterStateCache:attributeCacheContainer.realContainer
                                                       endpoint:endpoint
                                                          queue:queue
                                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                         // Cast is safe because subclass does not add any selectors.
                                                         completionHandler(static_cast<NSArray *>(value), error);
                                                     }];
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSArray *>(value), error);
    }];
}
- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeAttributeListWithParams:subscribeParams
                            subscriptionEstablished:subscriptionEstablishedHandler
                                      reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                          // Cast is safe because subclass does not add any selectors.
                                          reportHandler(static_cast<NSArray *>(value), error);
                                      }];
}
+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeAttributeListWithClusterStateCache:attributeCacheContainer.realContainer
                                                 endpoint:endpoint
                                                    queue:queue
                                               completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                   // Cast is safe because subclass does not add any selectors.
                                                   completionHandler(static_cast<NSArray *>(value), error);
                                               }];
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeFeatureMapWithParams:subscribeParams
                         subscriptionEstablished:subscriptionEstablishedHandler
                                   reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                       // Cast is safe because subclass does not add any selectors.
                                       reportHandler(static_cast<NSNumber *>(value), error);
                                   }];
}
+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeFeatureMapWithClusterStateCache:attributeCacheContainer.realContainer
                                              endpoint:endpoint
                                                 queue:queue
                                            completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                // Cast is safe because subclass does not add any selectors.
                                                completionHandler(static_cast<NSNumber *>(value), error);
                                            }];
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<NSNumber *>(value), error);
    }];
}
- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    MTRSubscribeParams * _Nullable subscribeParams = [params copy];
    if (subscribeParams == nil) {
        subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
    } else {
        subscribeParams.minInterval = minInterval;
        subscribeParams.maxInterval = maxInterval;
    }
    [self subscribeAttributeClusterRevisionWithParams:subscribeParams
                              subscriptionEstablished:subscriptionEstablishedHandler
                                        reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                            // Cast is safe because subclass does not add any selectors.
                                            reportHandler(static_cast<NSNumber *>(value), error);
                                        }];
}
+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    [self readAttributeClusterRevisionWithClusterStateCache:attributeCacheContainer.realContainer
                                                   endpoint:endpoint
                                                      queue:queue
                                                 completion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                                                     // Cast is safe because subclass does not add any selectors.
                                                     completionHandler(static_cast<NSNumber *>(value), error);
                                                 }];
}

- (nullable instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

@end

// NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks)
